How to count the number of identical letters in a string in RPG - rpgle

I would like to count the number of 'i' in the name 'olivia' but I have the impression that my condition is not valid?
How to do charAt in RPG 4 please?
FOR i = 1 to %len(name);
IF %check(name : letter) = 0;
count += 1;
ENDIF;
ENDFOR;
Here is the complete code:
**free
dcl-s name varchar(50);
dcl-s letter char(1);
dcl-s count packed(2:0);
dcl-s i packed(3:0);
dcl-s waitInput char(1);
dcl-s message varchar(50);
name = 'olivia';
letter = 'i';
count = 0;
FOR i = 1 to %len(name);
IF %check(name : letter) = 0;
count += 1;
ENDIF;
ENDFOR;
message = 'The name ' + %char(name) + ' has ' + %char(count) + 'time(s) the letter ' + (letter) ;
dsply message '' waitInput;
*INLR = *on;

IF %check(name : letter) = 0;
=>
IF %subst(name :i:1) = letter;

Related

How do I print a shuffled order of strings that never repeat? ARDUINO

I'm trying to make a scramble generator for the rubik's cube, every letter corresponds to a move on the cube, but I don't want that two moves get printed next to each other, for example " R R U U2 L' " because that would make quite inefficient that scramble. I'll paste part of the code down below:
char a0[] = "R ";
char a1[] = "L' ";
char a2[] = "B' ";
char a3[] = "D2 ";
char a4[] = "F ";
char a5[] = "U2 ";
int moveA;
for (int i=0; i < 6; i++)
{
moveA = random(0,5);
if (moveA == 0)
Serial.print(a0);
else if (moveA == 1)
Serial.print(a1);
else if (moveA == 2)
Serial.print(a2);
else if (moveA == 3)
Serial.print(a3);
else if (moveA == 4)
Serial.print(a4);
else if (moveA == 5)
Serial.print(a5);
delay(200);
The output is usually something like
B' F D2 D2 R B'
F2 D' D' F2 R2 R2
You can put the moves in an array and then shuffle the array:
const char *moves[] = {"R ", "L' ", "B' ", "D2 ", "F ", "U2 "};
const int num_moves = sizeof(moves) / sizeof(moves[0]);
// Shuffle
for (int i = num_moves - 1; i > 0; i--)
{
// Random index 0 ≤ j ≤ i
int j = random(0, i + 1);
// Swap
const char *tmp = moves[i];
moves[i] = moves[j];
moves[j] = tmp;
}
for (int i = 0; i < num_moves; i++)
{
Serial.print(moves[i]);
delay(200);
}
See: Fisher–Yates shuffle

IBM ILE RPG - How to store time values greater than 24h

How can I store time values (e.g.: 33h 24m 02s) in a TIME variable since *HIVAL - the max value - is 24h 00m 00s.
When storing it in a data structure (DS) sometimes (when a values is less than 10) e.g: 33:24:03 the value is displayed as 33.24.3 since the field is not padding with zeros automatically
Well you have already answered your own question, the limit is 24 hours.
I'm not sure what you are trying to accomplish, but I would suggest you use the %diff() Built-in Function (BIF) to get the difference between the two time/date/timestamp values and store it in an integer. And then to manipulate another time/timestamp field you could use the %seconds() BIF.
For example:
ctl-opt dftactgrp(*no) actgrp(*new);
ctl-opt timfmt(*iso);
dcl-s time1 time inz(t'09.25.00');
dcl-s time2 time inz(t'10.00.00');
dcl-s time3 time;
dcl-s SecondsDiff int(10);
dcl-s result char(1);
SecondsDiff = %diff(time2: time1: *seconds);
time3 = %time() + %seconds(SecondsDiff);
dsply ('In 35 minutes it will be: ' + %char(time3)) '*EXT' result;
*inlr = *on;
This is a very simplistic example, if you could give me more information to what you are trying to accomplish I could give a more specific example.
Edit
Here is a sample procedure that will do what you are requesting:
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s SecondsChar char(20);
dcl-s Result varchar(32);
dcl-s WaitAnyKey char(1);
dsply 'Enter an amount of seconds: ' '*EXT' SecondsChar;
Result = SecondsToDisplay(%int(SecondsChar));
dsply Result '*EXT' WaitAnyKey;
*inlr = *on;
dcl-proc SecondsToDisplay;
dcl-pi *n varchar(32);
Seconds int(10) value;
end-pi;
dcl-s Result varchar(32) inz('');
dcl-s CurrentValue int(10);
Seconds = %abs(Seconds);
//Get the days
CurrentValue = Seconds / 86400;
if (CurrentValue > 0);
Result = %char(CurrentValue) + 'd ';
Seconds = %rem(Seconds: 86400);
endif;
//Get the hours
CurrentValue = Seconds / 3600;
if (CurrentValue > 0 OR Result <> '');
Result += %char(CurrentValue) + 'h ';
Seconds = %rem(Seconds: 3600);
endif;
//Get the minutes
CurrentValue = Seconds / 60;
if (CurrentValue > 0 OR Result <> '');
Result += %char(CurrentValue) + 'm ';
Seconds = %rem(Seconds: 60);
endif;
//The seconds
Result += %char(Seconds) + 's';
return Result;
end-proc;
And some sample output:
DSPLY Enter an amount of seconds: 799240
DSPLY 9d 6h 0m 40s

How should I fix my infinite while loop that takes in 3 conditions? Also stylistic questions for novice

writing code to test the Hailstone Sequence, also called Collatz conjecture. Code will print out the number of iterations of the Hailstone sequence.
def main():
start_num = eval (input ("Enter starting number of the range: "))
end_num = eval (input ("Enter ending number of the range: "))
The main problem is that my code returns an infinite loop. I want to check all of these conditions in one statement
while (start_num > 0 and end_num > 0 and end_num > start_num):
cycle_length = 0
max_length = 0
max_number = 0
my code seems inefficient, there is probably a better way to approach the problem
for i in range(start_num, (end_num + 1)):
cycle_length = 0
while (i != 1):
if (i % 2 == 0):
i = i // 2
cycle_length += 1
if (i % 2 == 1):
i = ((3 * i) + 1)
cycle_length += 1
print (cycle_length)
I just started coding, and I always know that there is a more efficient way to approach these problems. Any suggestions on methodology, problem solving, or stylistic advice would be greatly appreciated.
Here is an answer in java. I assume that we will not start with 1.
public static void main(String[] args) {
int counter =0;
Scanner sc = new Scanner(System.in);
System.out.println("Give us a number to start with:");
int start = sc.nextInt();
System.out.println("Give us a number to end with:");
int end = sc.nextInt();
if (end > start) {
for (int i = 0; i <= end - start; i++) {
counter = 0;
int num = start + i;
int temp = num;
while(temp != 1) {
if ( temp % 2 == 0 ) {
temp = temp / 2;
} else {
temp = 3* temp +1;
}
counter++;
}
System.out.println(num + " takes " + counter + "iterations.");
}
} else {
System.out.println("Your numbers do not make sense.");
}
}
Here's an answer in python in case you're staying up late trying to solve this problem. :P Have a good night.
start_num = 1
end_num = 10
for i in range(start_num, (end_num + 1)):
cycle_length=0
num = i
while (num != 1):
if (num % 2 == 0):
num = num // 2
cycle_length+=1
else:
num = ((3 * num) + 1)
cycle_length+=1
print(cycle_length)

Counting substring that begin with character 'A' and ends with character 'X'

PYTHON QN:
Using just one loop, how do I devise an algorithm that counts the number of substrings that begin with character A and ends with character X? For example, given the input string CAXAAYXZA there are four substrings that begin with A and ends with X, namely: AX, AXAAYX, AAYX, and AYX.
For example:
>>>count_substring('CAXAAYXZA')
4
Since you didn't specify a language, im doing c++ish
int count_substring(string s)
{
int inc = 0;
int substring_count = 0;
for(int i = 0;i < s.length();i++)
{
if(s[i] == 'A') inc++;
if(s[i] == 'X') substring_count += inc;
}
return substring_count;
}
and in Python
def count_substring(s):
inc = 0
substring_count = 0
for c in s:
if(c == 'A'): inc = inc + 1
if(c == 'X'): substring_count = substring_count + inc
return substring_count
First count number of "A" in the string
Then count "X" in the string
using
Public Function CountCharacter(ByVal value As String, ByVal ch As Char) As Integer
Dim cnt As Integer = 0
For Each c As Char In value
If c = ch Then cnt += 1
Next
Return cnt
End Function
then take each "A" as a start position and "X" as an end position and get the substring. Do this for each "X" and then start with second "A" and run that for "X" count times. Repeat this and you will get all the substrings starting with "A" and ending with "X".
Just another solution In python:
def count_substring(str):
length = len(str) + 1
found = []
for i in xrange(0, length):
for j in xrange(i+1, length):
if str[i] == 'A' and str[j-1] == 'X':
found.append(str[i:j])
return found
string = 'CAXAAYXZA'
print count_substring(string)
Output:
['AX', 'AXAAYX', 'AAYX', 'AYX']

Encode and decode an Adobe Dreamweaver password in *.ste file

How is a password encoded or decoded in order to retrieve a password from an Adobe Dreamweaver *.ste file, or to dynamically create a *.ste file designed to be imported into Dreamweaver?
This Javascript function can be used to encode the password:
function encodePassword(input)
{
var top = 0;
var output = '';
for(var i = 0; i < input.length; i++){
var currentChar = input.charCodeAt(i);
if(currentChar < 0 || currentChar > 0xFFFF){return(false);}
if(top != 0){
if(0xDC00 <= currentChar && currentChar <= 0xDFFF){
output += dec2hex(0x10000 + ((top - 0xD800) << 10) + (currentChar - 0xDC00) + i) + '';
top = 0;
continue;
// Insert alert for below failure
}else{return(false);}
}
if(0xD800 <= currentChar && currentChar <= 0xDBFF){top = currentChar;}
else{output += dec2hex(currentChar + i) + '';}
}
return(output);
}
function dec2hex(input){return(input+0).toString(16).toUpperCase();}
And this function can be used to decode the password:
function decodePassword(input)
{
var output = "";
if(input.length == 0){return("");}
for(var i = 0; i < input.length / 2; i++){
var currentHex = parseInt(input.substr(i * 2, 2), 16);
if(currentHex <= 0xFFFF){
output += String.fromCharCode(currentHex - i);
}else if(currentHex <= 0x10FFFF){
currentHex -= 0x10000
output += String.fromCharCode(0xD800 | (currentHex >> 10)) + String.fromCharCode(0xDC00 | (currentHex & 0x3FF) - i);
}else{
//Insert alert for below failure
return(false);
}
}
return(output);
}
You can also do this online without any code using this tool: http://blog.affirmix.com/2009/05/05/live-ste-dreamweaver-password-encoder-and-decoder/
To decode the Dreamweaver password you break the password into pairs of hexadecimal (0-9, A-F) digits then subtract from each hex digit based on it's position in the string, starting with 0, then convert back to ascii.
The encrypted password of 5470714865787F would be...
54-0 = 54 => T
70-1 = 6F => o
71-2 = 6F => o
48-3 = 45 => E
65-4 = 61 => a
78-5 = 73 => s
7F-6 = 79 => y
So 5470714865787F => 'TooEasy'
We have a working example of this on our website which allows you to decode your password. You can also copy/paste your entire .ste file and it will output the needed FTP details to connect, save some time...
http://www.mywebsitespot.com/dreamweaver-password-decode
Sorry to wake up an old thread but thought I'd post my solution. It's a single HTML5 page that can load and parse Dreamweaver STE files, decoding the password as part of that. I wanted something simple, offline/local (so details aren't transmitted when decoding) that I could to just load an STE file in to and it would give me all the FTP details:
Blog Post:
http://bobmckay.com/web/dreamweaver-password-ste-file-decoder
Decoder Page:
http://bobmckay.com/dreamweaver-password-decoder/
Hope it's useful to someone!
Bob
Waking an old thread, but in addition to the accepted JavaScript answer, I just wanted to leave two PHP functions for anyone interested:
To encode a password:
function dwste_encode( $pw ){
$output = '';
$split = str_split( $pw );
foreach( $split as $key => $value ){
$char = ord( $value );
$char = ( $char + $key );
$char = dechex( $char );
$output .= strtoupper( $char );
}
return $output;
}
To decode a password:
function dwste_decode( $pw ){
$output = '';
$split = str_split( $pw, 2 );
foreach( $split as $key => $value ){
$char = hexdec( $value );
$char = ( $char - $key );
$char = chr( $char );
$output .= $char;
}
return $output;
}
I needed to create many DW ste files for a client today. I used the following VBA to do it straight from Excel. I used the code from #andrew-odri as the basis.
Function decodeDreamWeaverPass(sHash$)
Dim sPass$, i&, lHash&, lChar&, sChars$
lHash = Len(sHash) - 1
For i = 0 To lHash Step 2
sChars = Mid(sHash, i + 1, 2)
lChar = CLng("&H" & sChars)
lChar = lChar - (i / 2)
sPass = sPass & Chr(CLng(lChar))
Next
decodeDreamWeaverPass = sPass
End Function
Function encodeDreamWeaverPass(sPassword$)
Dim lTop&, i&, sOutput$
Dim lPassword&, sChar$, lChar&
lTop = 0
lPassword = Len(sPassword) - 1
For i = 0 To lPassword
lChar = Asc(Mid(sPassword, i + 1, 1))
sChar = Chr(lChar)
If ((lChar < 0) Or (lChar > 65535)) Then
encodeDreamWeaverPass = ""
End If
If lTop > 0 Then
If (lChar >= 56320) And (lChar <= 57343) Then
sOutput = sOutput & Hex(65536 + ((lTop - 55296) Xor 10) + (lChar - 56320) + i)
lTop = 0
Else
encodeDreamWeaverPass = ""
End If
End If
If (lChar >= 55296) And (lChar <= 56319) Then
lTop = lChar
Else
sOutput = sOutput & Hex(lChar + i)
End If
Next
encodeDreamWeaverPass = sOutput
End Function

Resources