[[{“value”:”Pairing open source with traditional IBM i programs works great for APIs, web, and mobile applications. But how do you stay on top of your business’s requirements for speed and scalability? OCEAN User Group recently asked Alan to help answer that question. In the recording of their November meeting (also linked from the graphic below), he covers: How to use QSHCURL with RPG or CL to get content from HTTP or APIs, find network issues, send email, and more Advances in Git source control and package security Tips on using IBM’s ODBC driver, and when to consider Mapepire Ways to…
The post Integrating Open Source on IBM i: Advanced Topics and Optimization appeared first on Seiden Group.”}]] Read More
Robot | 2025 IBM i Executive Briefing Fortra
[[{“value”:”Watch our 2025 IBM i Executive Briefing to learn more about how we’re honoring our commitment to this exceptional platform, including what we’ve been working on in 2024 and what’s to come in the new year.
Since HelpSystems became Fortra two years ago, a few things have remained the same: Our commitment to creating exceptional products, remaining an active voice within the IBM i community, and creating lasting relationships with our customers.”}]] Read More
RPGLE and CLLE Copybooks with VS Code NickLitten
We’ve previously spoken about how to use /COPY and /INCLUDE in our RPGLE programs. We also covered how to use the INCLUDE command in our CLLE programs more Join me while I walk through using a real-world example in Visual Studio Code for IBM i more We’ve previously spoken about how to use /COPY and Read More
CYBRA Unveils MarkMagic 11: The Next Evolution in Enterprise Label and Form Printing
CYBRA software solutions run on all major computing platforms, including Microsoft Windows, Linux, Unix, cloud and IBM Power Systems (System i, … Read More
Advent of Code 2024 day 10, RPG edition
[[{“value”:”This is the eleventh day of Advent of Code, let’s solve today’s puzzles with RPG.
The puzzle as well as the input data are available here.
The code is available here.
Part 1
We are provided with a (stream) file containing numbers engraved on stones.
Each time we blink, the number on the stones and the number of stones changes (see the rules in the puzzle definition).
We need to calculate how many stones there will be after blinking 25 times.
As usual, we read the input file with QSYS2.IFS_READ_UTF8 table function.
We load the values in a dynamic array with %SPLIT built-in function.
We loop 25 times and apply the rules to each stone value to build the next iteration array.
The result is the number of elements in the array after the last iteration.
Here is the RPG code for part 1:
**free
ctl-opt dftactgrp(*no); // We’re using procedure so we can’t be in the default activation group
dcl-pi *n;
input char(50);
end-pi;
dcl-s fileName varchar(50);
dcl-s data char(255);
dcl-s value char(255);
dcl-s i int(5);
dcl-s stone int(20);
dcl-s result int(10) inz(0);
dcl-s currentState int(20) dim(*auto:1677310);
dcl-s newState int(20) dim(*auto:1677310);
fileName = %trim(input);
// Read the input data from the IFS
exec sql select line into :data from table(qsys2.ifs_read_utf8(path_name => :fileName));
// Load current State from input data
for-each value in %split(data);
currentState(*next) = %int(value);
endfor;
for i = 1 to 25;
for-each stone in currentState;
if stone = 0;
newState(*next) = 1;
else;
if %rem(%len(%char(stone)):2) = 0;
newState(*next) = %int(%subst(%char(stone):1:%div(%len(%char(stone)):2)));
newState(*next) = %int(%subst(%char(stone):%div(%len(%char(stone)):2)+1));
else;
newState(*next) = stone*2024;
endif;
endif;
endfor;
currentState = newState;
%elem(newState) = 0;
endfor;
result = %elem(currentState);
snd-msg *info ‘Result: ‘ + %char(result) %target(*pgmbdy:1); // Send message with answer
*inlr = *on;
return;
Part 2
Part 2 definition is extremely simple: you blink 75 times instead of 25.
The obvious solution is to change the loop to iterate 75 times instead of 25. Problem is the method used in part 1 is exponential in memory and processing required so it’s basically impossible to do 75 iterations (with my input data, the final array alone would have used more than 3 PB of memory).
Although the number of stones grows exponentially and gets really huge, the number of distinct values on the stones is significantly lower (3772 after 75 iterations with my data) and the order and position of the stones is totally irrelevant (on the value of a stone determines what happens to it during an iteration) therefore, we only need to keep track of the different values on the stones and the number of stones with each value.
Each iteration becomes very fast and the memory needed is very low (the final array uses 60 KB with my input data).
After the last iteration, we just need to sum the number of stones for each value.
**free
ctl-opt dftactgrp(*no); // We’re using procedure so we can’t be in the default activation group
dcl-pi *n;
input char(50);
end-pi;
dcl-pr addState;
stone uns(20) value;
count uns(20) value;
end-pr;
dcl-s fileName varchar(50);
dcl-s data char(255);
dcl-s value char(255);
dcl-s result uns(20) inz(0);
dcl-s stone uns(20);
dcl-ds state qualified;
stone uns(20);
count uns(20);
end-ds;
dcl-ds currentState likeds(state) dim(*auto:1000000);
dcl-ds newState likeds(state) dim(*auto:1000000);
dcl-s i int(5);
fileName = %trim(input);
// Read the input data from the IFS
exec sql select line into :data from table(qsys2.ifs_read_utf8(path_name => :fileName));
// Load current State from input data
for-each value in %split(data);
state.stone = %int(value);
state.count = 1;
currentState(*next) = state;
endfor;
for i = 1 to 75;
for-each state in currentState;
if state.stone = 0;
addState(1:state.count);
else;
if %rem(%len(%char(state.stone)):2) = 0;
addState(%int(%subst(%char(state.stone):1:%div(%len(%char(state.stone)):2))):state.count);
addState(%int(%subst(%char(state.stone):%div(%len(%char(state.stone)):2)+1)):state.count);
else;
addState(state.stone*2024:state.count);
endif;
endif;
endfor;
%elem(currentState) = %elem(newState);
currentState = newState;
%elem(newState) = 0;
endfor;
for-each state in currentState;
result += state.count;
endfor;
snd-msg *info ‘Result: ‘ + %char(result) %target(*pgmbdy:1); // Send message with answer
*inlr = *on;
return;
dcl-proc addState;
dcl-pi *n;
stone uns(20) value;
count uns(20) value;
end-pi;
dcl-ds wState likeds(state);
dcl-s i int(10);
i = %lookup(stone:newState(*).stone);
if i = 0;
wState.stone = stone;
wState.count = count;
newState(*next) = wState;
else;
newState(i).count += count;
endif;
end-proc;”}]] Read More