David Jondreau Posted July 8, 2010 Posted July 8, 2010 Here's a new puzzler.... Build a Rot13() custom function. It should take a string and rotate each letter 13 places in the alphabet. Wiki Rot13 for more details. The function should only affect the letters on a string: A-Z and a-z. If you don't have Advanced, do the above, but for single characters and wrap it in a Looping script. Bonus points if you can do a string without a recursive custom function or looping. (I couldn't figure out how.) Bonus points if you build it so any integer can be entered as a parameter in the function, creating a general Caesar cipher. To keep it interesting, don't refer to any Filemaker resources outside of the FMP help files (ie no searching this site, or Dunning's custom function site, etc). Tbbq yhpx!
TheTominator Posted July 8, 2010 Posted July 8, 2010 No recursive or looping. It does require that the original text not contain any sequence that looks like "_nn_" where nn is a two digit number from 1 to 26. If there is likely to be such an odd string, you can change the intermediate format to something even more obscure. /* Rot13(text) */ /* */ Substitute( Substitute( text; ["a";"_01_"]; ["b";"_02_"]; ["c";"_03_"]; ["d";"_04_"]; ["e";"_05_"]; ["f";"_06_"]; ["g";"_07_"]; ["h";"_08_"]; ["i";"_09_"]; ["j";"_10_"]; ["k";"_11_"]; ["l";"_12_"]; ["m";"_13_"]; ["n";"_14_"];["o";"_15_"]; ["p";"_16_"]; ["q";"_17_"]; ["r";"_18_"]; ["s";"_19_"]; ["t";"_20_"]; ["u";"_21_"]; ["v";"_22_"]; ["w";"_23_"]; ["x";"_24_"]; ["y";"_25_"]; ["z";"_26_"]); ["_01_";"n"]; ["_02_";"o"]; ["_03_";"p"]; ["_04_";"q"]; ["_05_";"r"]; ["_06_";"s"]; ["_07_";"t"]; ["_08_";"u"]; ["_09_";"v"]; ["_10_";"w"]; ["_11_";"x"]; ["_12_";"y"]; ["_13_";"z"]; ["_14_";"a"];["_15_";"b"]; ["_16_";"c"]; ["_17_";"d"]; ["_18_";"e"]; ["_19_";"f"]; ["_20_";"g"]; ["_21_";"h"]; ["_22_";"i"]; ["_23_";"j"]; ["_24_";"k"]; ["_25_";"l"]; ["_26_";"m"] )
TheTominator Posted July 8, 2010 Posted July 8, 2010 /* CeasarCipher(text; offset) */ /* */ Substitute( Substitute( text; ["a";"_" & Mod(1 + offset;26) & "_"]; ["b";"_" & Mod(2 + offset;26) & "_"]; ["c";"_" & Mod(3 + offset;26) & "_"]; ["d";"_" & Mod(4 + offset;26) & "_"]; ["e";"_" & Mod(5 + offset;26) & "_"]; ["f";"_" & Mod(6 + offset;26) & "_"]; ["g";"_" & Mod(7 + offset;26) & "_"]; ["h";"_" & Mod(8 + offset;26) & "_"]; ["i";"_" & Mod(9 + offset;26) & "_"]; ["j";"_" & Mod(10 + offset;26) & "_"]; ["k";"_" & Mod(11 + offset;26) & "_"]; ["l";"_" & Mod(12 + offset;26) & "_"]; ["m";"_" & Mod(13 + offset;26) & "_"]; ["n";"_" & Mod(14 + offset;26) & "_"];["o";"_" & Mod(15 + offset;26) & "_"]; ["p";"_" & Mod(16 + offset;26) & "_"]; ["q";"_" & Mod(17 + offset;26) & "_"]; ["r";"_" & Mod(18 + offset;26) & "_"]; ["s";"_" & Mod(19 + offset;26) & "_"]; ["t";"_" & Mod(20 + offset;26) & "_"]; ["u";"_" & Mod(21 + offset;26) & "_"]; ["v";"_" & Mod(22 + offset;26) & "_"]; ["w";"_" & Mod(23 + offset;26) & "_"]; ["x";"_" & Mod(24 + offset;26) & "_"]; ["y";"_" & Mod(25 + offset;26) & "_"]; ["z";"_" & Mod(26 + offset;26) & "_"]); ["_1_";"a"]; ["_2_";"b"]; ["_3_";"c"]; ["_4_";"d"]; ["_5_";"e"]; ["_6_";"f"]; ["_7_";"g"]; ["_8_";"h"]; ["_9_";"i"]; ["_10_";"j"]; ["_11_";"k"]; ["_12_";"l"]; ["_13_";"m"]; ["_14_";"n"];["_15_";"o"]; ["_16_";"p"]; ["_17_";"q"]; ["_18_";"r"]; ["_19_";"s"]; ["_20_";"t"]; ["_21_";"u"]; ["_22_";"v"]; ["_23_";"w"]; ["_24_";"x"]; ["_25_";"y"]; ["_0_";"z"] )
TheTominator Posted July 8, 2010 Posted July 8, 2010 Cipher solution breaks when numbers appear in the message. I think using something like "{{1}}" instead of "_1_" should fix it. Just to be safe, the same convention should be used in my Rot13() too.
David Jondreau Posted July 8, 2010 Author Posted July 8, 2010 Good try...definitely doing it the hard way. I was looking for something that would work with upper and lower case letters and I'm not sure using obscure delimiters meets the criteria...unlikely, but someone might validly use {{1}} in a text.
TheTominator Posted July 8, 2010 Posted July 8, 2010 (edited) I was looking for something that would work with upper and lower case letters The Rot13() could be augmented with all of the uppercase substitutions. Trivial but tedious. The similarly coded CaesarCipher() would need additional substitutions for upper case. Using "{{1}}} for "a" and {^1^} for "A" should keep the cases separate. For another submission here's a recursive function that is limited to FileMaker's 10,000 nesting for head recursion. Thus 10,000 char limit. Handles upper and lower case. /* Caesar_cf(text; offset) */ /* recursive function */ /* */ Let( [ n = Length(text); x = Code(Left(text;1)); yuo = Mod(x - 96 + offset; 26); ylo = Mod(x - 64 + offset; 26) ]; Case( n = 0; ""; Case( x > (97+25); Char(x); // > z x < (65); Char(x); // < A (x > 90) and (x < 97); Char(x); // Z < x < a x ≥ 97; If(yuo; Char(yuo + 96); "z"); // a-z If(ylo; Char(ylo + 64); "Z") // A-Z ) & Caesar_cf(Right(text;n - 1); offset) )) Edited July 8, 2010 by Guest
TheTominator Posted July 8, 2010 Posted July 8, 2010 For the sake of completeness, here is the brute force Substitute method handling upper and lowercase. /* CeasarCipher(text; offset) */ /* */ Substitute( Substitute( text; ["a";"{{" & Mod(1 + offset;26) & "}}"]; ["b";"{{" & Mod(2 + offset;26) & "}}"]; ["c";"{{" & Mod(3 + offset;26) & "}}"]; ["d";"{{" & Mod(4 + offset;26) & "}}"]; ["e";"{{" & Mod(5 + offset;26) & "}}"]; ["f";"{{" & Mod(6 + offset;26) & "}}"]; ["g";"{{" & Mod(7 + offset;26) & "}}"]; ["h";"{{" & Mod(8 + offset;26) & "}}"]; ["i";"{{" & Mod(9 + offset;26) & "}}"]; ["j";"{{" & Mod(10 + offset;26) & "}}"]; ["k";"{{" & Mod(11 + offset;26) & "}}"]; ["l";"{{" & Mod(12 + offset;26) & "}}"]; ["m";"{{" & Mod(13 + offset;26) & "}}"]; ["n";"{{" & Mod(14 + offset;26) & "}}"];["o";"{{" & Mod(15 + offset;26) & "}}"]; ["p";"{{" & Mod(16 + offset;26) & "}}"]; ["q";"{{" & Mod(17 + offset;26) & "}}"]; ["r";"{{" & Mod(18 + offset;26) & "}}"]; ["s";"{{" & Mod(19 + offset;26) & "}}"]; ["t";"{{" & Mod(20 + offset;26) & "}}"]; ["u";"{{" & Mod(21 + offset;26) & "}}"]; ["v";"{{" & Mod(22 + offset;26) & "}}"]; ["w";"{{" & Mod(23 + offset;26) & "}}"]; ["x";"{{" & Mod(24 + offset;26) & "}}"]; ["y";"{{" & Mod(25 + offset;26) & "}}"]; ["z";"{{" & Mod(26 + offset;26) & "}}"]; ["A";"{^" & Mod(1 + offset;26) & "^}"]; ["B";"{^" & Mod(2 + offset;26) & "^}"]; ["C";"{^" & Mod(3 + offset;26) & "^}"]; ["D";"{^" & Mod(4 + offset;26) & "^}"]; ["E";"{^" & Mod(5 + offset;26) & "^}"]; ["F";"{^" & Mod(6 + offset;26) & "^}"]; ["G";"{^" & Mod(7 + offset;26) & "^}"]; ["H";"{^" & Mod(8 + offset;26) & "^}"]; ["I";"{^" & Mod(9 + offset;26) & "^}"]; ["J";"{^" & Mod(10 + offset;26) & "^}"]; ["K";"{^" & Mod(11 + offset;26) & "^}"]; ["L";"{^" & Mod(12 + offset;26) & "^}"]; ["M";"{^" & Mod(13 + offset;26) & "^}"]; ["N";"{^" & Mod(14 + offset;26) & "^}"];["O";"{^" & Mod(15 + offset;26) & "^}"]; ["P";"{^" & Mod(16 + offset;26) & "^}"]; ["Q";"{^" & Mod(17 + offset;26) & "^}"]; ["R";"{^" & Mod(18 + offset;26) & "^}"]; ["S";"{^" & Mod(19 + offset;26) & "^}"]; ["T";"{^" & Mod(20 + offset;26) & "^}"]; ["U";"{^" & Mod(21 + offset;26) & "^}"]; ["V";"{^" & Mod(22 + offset;26) & "^}"]; ["W";"{^" & Mod(23 + offset;26) & "^}"]; ["X";"{^" & Mod(24 + offset;26) & "^}"]; ["Y";"{^" & Mod(25 + offset;26) & "^}"]; ["Z";"{^" & Mod(26 + offset;26) & "^}"]); ["{{1}}";"a"]; ["{{2}}";"b"]; ["{{3}}";"c"]; ["{{4}}";"d"]; ["{{5}}";"e"]; ["{{6}}";"f"]; ["{{7}}";"g"]; ["{{8}}";"h"]; ["{{9}}";"i"]; ["{{10}}";"j"]; ["{{11}}";"k"]; ["{{12}}";"l"]; ["{{13}}";"m"]; ["{{14}}";"n"];["{{15}}";"o"]; ["{{16}}";"p"]; ["{{17}}";"q"]; ["{{18}}";"r"]; ["{{19}}";"s"]; ["{{20}}";"t"]; ["{{21}}";"u"]; ["{{22}}";"v"]; ["{{23}}";"w"]; ["{{24}}";"x"]; ["{{25}}";"y"]; ["{{0}}";"z"]; ["{^1^}";"A"]; ["{^2^}";"B"]; ["{^3^}";"C"]; ["{^4^}";"D"]; ["{^5^}";"E"]; ["{^6^}";"F"]; ["{^7^}";"G"]; ["{^8^}";"H"]; ["{^9^}";"I"]; ["{^10^}";"J"]; ["{^11^}";"K"]; ["{^12^}";"L"]; ["{^13^}";"M"]; ["{^14^}";"N"];["{^15^}";"O"]; ["{^16^}";"P"]; ["{^17^}";"Q"]; ["{^18^}";"R"]; ["{^19^}";"S"]; ["{^20^}";"T"]; ["{^21^}";"U"]; ["{^22^}";"V"]; ["{^23^}";"W"]; ["{^24^}";"X"]; ["{^25^}";"Y"]; ["{^0^}";"Z"] )
Raybaudi Posted July 8, 2010 Posted July 8, 2010 What about something along this line ? ( still in progress for simplify and complete ) Substitute ( Substitute ( text ; [ Char ( 65 ) ; Char ( 1000 ) ] ; [ Char ( 66 ) ; Char ( 1001 ) ] ; [ Char ( 67 ) ; Char ( 1002 ) ] ; [ Char ( 68 ) ; Char ( 1003 ) ] ; [ Char ( 69 ) ; Char ( 1004 ) ] ; [ Char ( 70 ) ; Char ( 1005 ) ] ; [ Char ( 71 ) ; Char ( 1006 ) ] ; [ Char ( 72 ) ; Char ( 1007 ) ] ; [ Char ( 73 ) ; Char ( 1008 ) ] ; [ Char ( 74 ) ; Char ( 1009 ) ] ; [ Char ( 75 ) ; Char ( 1010 ) ] ; [ Char ( 76 ) ; Char ( 1011 ) ] ; [ Char ( 77 ) ; Char ( 1012 ) ] ; [ Char ( 78 ) ; Char ( 1013 ) ] ; [ Char ( 79 ) ; Char ( 1014 ) ] ; [ Char ( 80 ) ; Char ( 1015 ) ] ; [ Char ( 81 ) ; Char ( 1016 ) ] ; [ Char ( 82 ) ; Char ( 1017 ) ] ; [ Char ( 83 ) ; Char ( 1018 ) ] ; [ Char ( 84 ) ; Char ( 1019 ) ] ; [ Char ( 85 ) ; Char ( 1020 ) ] ; [ Char ( 86 ) ; Char ( 1021 ) ] ; [ Char ( 87 ) ; Char ( 1022 ) ] ; [ Char ( 88 ) ; Char ( 1023 ) ] ; [ Char ( 89 ) ; Char ( 1024 ) ] ; [ Char ( 90 ) ; Char ( 1025 ) ] ) ; [ Char ( 1000 ) ; Char ( 78 ) ] ; [ Char ( 1001 ) ; Char ( 79 ) ] ; [ Char ( 1002 ) ; Char ( 80 ) ] ; [ Char ( 1003 ) ; Char ( 81 ) ] ; [ Char ( 1004 ) ; Char ( 82 ) ] ; [ Char ( 1005 ) ; Char ( 83 ) ] ; [ Char ( 1006 ) ; Char ( 84 ) ] ; [ Char ( 1007 ) ; Char ( 85 ) ] ; [ Char ( 1008 ) ; Char ( 86 ) ] ; [ Char ( 1009 ) ; Char ( 87 ) ] ; [ Char ( 1010 ) ; Char ( 88 ) ] ; [ Char ( 1011 ) ; Char ( 89 ) ] ; [ Char ( 1012 ) ; Char ( 90 ) ] ; [ Char ( 1013 ) ; Char ( 65 ) ] ; [ Char ( 1014 ) ; Char ( 66 ) ] ; [ Char ( 1015 ) ; Char ( 67 ) ] ; [ Char ( 1016 ) ; Char ( 68 ) ] ; [ Char ( 1017 ) ; Char ( 69 ) ] ; [ Char ( 1018 ) ; Char ( 70 ) ] ; [ Char ( 1019 ) ; Char ( 71 ) ] ; [ Char ( 1020 ) ; Char ( 72 ) ] ; [ Char ( 1021 ) ; Char ( 73 ) ] ; [ Char ( 1022 ) ; Char ( 74 ) ] ; [ Char ( 1023 ) ; Char ( 75 ) ] ; [ Char ( 1024 ) ; Char ( 76 ) ] ; [ Char ( 1025 ) ; Char ( 77 ) ] )
Raybaudi Posted July 9, 2010 Posted July 9, 2010 My vote is for a recursive CF. /* Rot13 ( text ) */ Let( c = Code ( Left ( text ; 1 ) ) ; Case ( c ; Case( c > 64 and c < 91 ; Char ( Mod ( c - 52 ; 26 ) + 65 ) ; c > 96 and c < 123 ; Char ( Mod ( c - 84 ; 26 ) + 97 ) ; Char ( c ) ) & Rot13 ( Right ( text ; Length ( text ) - 1 ) ) ) )
David Jondreau Posted July 9, 2010 Author Posted July 9, 2010 Here's mine: Let([ var = Mod(var;26); thisChar = Left(text;1); num = Code(thisChar); type = Case( (num ≥ 65 and num ≤ 90) ; "upper"; num ≥ 97 and num ≤ 122; "lower" ; "non") ; rotted = num + Case( type = "non"; 0; var); adjust = Case( type = "upper" and rotted > 90; rotted -26; type = "lower" and rotted > 122; rotted - 26; rotted); newChar = Char(adjust); newText = Right(text; Length(text)-1); result = newChar & Case( Length(newText); Rot(newText; var)) ]; result )
Recommended Posts
This topic is 5249 days old. Please don't post here. Open a new topic instead.
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now