Splitting up ASCII

33

4

Given the 95 printable characters in ASCII plus newline, break it apart into two equal, 48 character groups (hereafter called group A and group B). Create a one-to-one mapping of your choice (you have total discretion) between the two groups. In other words, A might map to a, and vice versa, but A might also map to > and vice versa, if that's what you need for your program.

Once you've broken up ASCII into two groups, write two programs and/or functions, using only the characters in each group, respectively. In other words, write one program / function that only uses the characters in group A, and another program / function that only uses the characters in group B.

These programs must be able to receive one character as input. The program written with the characters in Group A should output / return the same character if the input was a group A character, and the mapped group A character if it received a group B character; the Group A program should always output a group A character. Similarly, the Group B program should output the same character if it's a group B character, and the mapped group B character if the input is a group A character.

That might not be so clear, so here's an example. If you assume that all capital letters are in group A, and all lowercase letters are in group B, and you've chosen that your one-to-one mapping for these letters are from one to the other, then: then here are some sample input/outputs:

Program A:

Input    Output
A        A
D        D
a        A
q        Q

Program B:

Input    Output
A        a
D        d
a        a
q        q

Other rules:

  • The two programs do not need to be in the same language.
  • They don't need to be both programs or both functions; one could be a program, the other a function, that is fine.
  • They don't need to work the same way, be of similar length, anything like that; they simply must meet the the other rules above.
  • Yes, only one of your programs may use newlines, and only one can use spaces (this could be the same, or a different program).
  • You do not need to use all 48 characters in each program.

Standard loopholes are banned, as normal. All programs must be self contained, no files containing the mapping you choose.

Scoring criteria: . Specifically, the sum of the bytes of the text of the two programs.

Please post your answer like this:

Language - # bytes + Language - # bytes = # bytes

An unambiguous description of your mapping. If it's complicated, use a chart like this:

ABCDEFGHIJKLMNOPQRSTUVWXYZ (etc.)
zyxwvutsrpqonmlkjihgfedcba (etc.)

Or, you can just explain it (first 48 maps to last 48 in sequence), followed by your answer as normal.

durron597

Posted 2015-09-04T22:03:12.913

Reputation: 4 692

I'm going to try using the same language for both. :) – mbomb007 – 2015-09-05T00:32:53.927

I honestly think you should change the rules, restricting it to "both programs have to be the same language." Otherwise it's probably WAY too easy/broad. – mbomb007 – 2015-09-05T01:29:37.967

I actually wonder if this is possible in Self-modifying Brainfuck. You just have to have one program using + and >, and the other using - and <. Then you have to try to generate the missing operators, such as a , or . in the program that cannot use them. – mbomb007 – 2015-09-05T01:37:06.320

If the implementation can be via two different functions within one program, can they share common code (i.e. a global variable)? – Ruslan – 2015-09-05T04:31:41.453

They can't be two functions in one program. If you do two functions it has to be in two programs. – durron597 – 2015-09-05T04:32:53.420

@durron597 Thanks! Also, does the restriction to repeat characters apply to non-alphanumeric characters as well? For instance, if I use the "=" symbol in the first program, I can't use it in the second one? – Ruslan – 2015-09-05T04:37:10.990

@durron597 Sorry, last question... If I opt for the two "function" approach, does only code inside of the actual function that takes the character and returns the mapped one count, or does the whole program still count? If the latter is the case, then the same language would simply be impossible (i.e. if both programs can't have "void main() { ... }" or "#include", etc). – Ruslan – 2015-09-05T04:40:52.170

@Ruslan It's the whole program. And then maybe you should try a different programming language, one without includes or required brackets. See if it's possible in Python. I think it is. – mbomb007 – 2015-09-05T06:00:19.167

I mean, one of them should be in brainfuck :) – Jamie – 2015-09-05T09:17:26.640

1@Ruslan Try using SQL. It's not case sensitive and uses keywords (begin and end) for code blocks. If you use SQL Server 2014, you can use DBCC Bulk Insert for one program, and a procedure for the other one. In the first one, you can avoid using parentheses. Then use a select case when statement for both programs.

Also, I believe it's possible in Java by using the \u trick for a program replacing every character with unicode values and using a function for the other that doesn't use the letter u, a backslash, or numbers. – bmarks – 2015-09-05T18:07:43.657

4Hardest. Challenge. Ever. – Blackhole – 2015-09-05T18:19:14.007

Was knee-deep into a solution using JavaScript for both; got tired but I'm almost positive it's possible. Figured out that a function normally requiring parentheses can be written without them, by creating a new Function with tagged template syntax and executing it with another tagged template. Then just a lot of hexadecimal escapes inside the eval'd string..... TL;DR this challenge is extremely difficult. – jrich – 2015-09-05T21:55:28.503

@Blackhole it's possible to complete if you use two sepearate languages: use Unary for one and Whitespace for the other. – bmarks – 2015-09-05T22:23:06.087

Exactly @bmarks with esolangs this is quite an easy challenge to complete... Doing it golfed is the hard part. – durron597 – 2015-09-05T22:32:57.837

@bmarks Yes, I also thought about SQL at first. But then one issue is spaces (although maybe I can find a way around that). – Ruslan – 2015-09-06T01:29:45.090

@Ruslan try using newlines in one and spaces in the other. I believe they are equivalent in T-SQL. – bmarks – 2015-09-06T01:31:41.300

Hmm, since the answer formatting is specified, I was expecting a leaderboard stack snippet :) – aditsu quit because SE is EVIL – 2015-09-08T18:16:33.487

@aditsu I suck at Javascript, but I welcome others to edit one in – durron597 – 2015-09-08T18:18:01.210

Answers

6

CJam - 11 bytes + CJam - 25 bytes = 36 bytes

Characters are selected in alternating groups of 16:

 !"#$%&'()*+,-./@ABCDEFGHIJKLMNO`abcdefghijklmno
0123456789:;<=>?PQRSTUVWXYZ[\]^_pqrstuvwxyz{|}~\n

It's cool that a few of the mappings can be obtained with the shift key :)

Program A:

lL,H-f&'o+c

Try it online

Program B:

q_S<\_0=16|_127<\S0=42^??

Try it online

Explanation:

Program A:

l      read a line from the input, this is a 1-character string
        or the empty string if the input was a newline
L,     get the length of an empty string/array (0)
H-     subtract 17, obtaining -17 (~16)
f&     bitwise-"and" each character (based on the ASCII code) with -17
'o+    append the 'o' character
c      convert to (first) character
        the result is the "and"-ed character, or 'o' for newline

Program B:

q_       read the whole input and duplicate it
S<\      compare with " " and move the result before the input
_0=      duplicate the input again, and get the first (only) character
16|      bitwise-"or" with 16 (based on the ASCII code)
_127<    duplicate and compare (its ASCII code) with 127
\        move the result before the "or"-ed character
S0=      get the space character (first character of the space string)
42^      xor with 42, obtaining a newline character
          stack: (input<" ") (input) ("or"-ed char<127) ("or"-ed char) (newline)
?        if the "or"-ed character is less than 127, use the "or"-ed character
          else use the newline character
?        if the input was smaller than space (i.e. it was a newline),
          use the input, else use the character from the previous step

aditsu quit because SE is EVIL

Posted 2015-09-04T22:03:12.913

Reputation: 22 326

Nice! Glad to see that "even/odd" isn't the only answer. – durron597 – 2015-09-08T18:15:28.393

Still a 1 bit toggle... Impressive sizes! 2nd program w/input of 'o' doesn't seem to output the \n... bug in program or online cjam? – Brian Tuck – 2015-09-09T04:32:43.853

@BrianTuck it does output a newline (not a literal \n), it's just not easy to see without inspecting the html. You can append an i at the end of the program to see the ASCII code instead (or ci to also deal with a newline input, since it outputs a newline string rather than a character in that case) – aditsu quit because SE is EVIL – 2015-09-09T07:07:04.707

Oh, or you/I could change _0= to 0=_ so that it always outputs a character – aditsu quit because SE is EVIL – 2015-09-09T07:20:18.393

16

CJam - 46 44 26 11 bytes + GolfScript - 142 125 115 93 68 47 40 36 bytes = 47 bytes

Thanks to Peter Taylor for golfing 6 bytes off the GolfScript program (and paving the way for many more.)

Thanks to Dennis for golfing 15 bytes off the CJam program and 4 bytes off the GolfScript program.

Group A: all characters with even character code.
Group B: all characters with odd character code, plus newline.

I'm using the obvious mapping between the two, i.e. pair those characters which only differ in the least significant bit, as well as ~ and \n. Here is the complete map (the columns):

 "$&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~
!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}\n

Program A (CJam, test it here):

lX~f&"~"|X<

Program B (GolfScript, test it here):

{1}'{-'{)}%'115)%11-[9)ie'9/{))}%++%

Explanation

Program A

(Outdated, will update tomorrow.)

This program should turn odd character codes into even ones, i.e. set the least significant bit to 0. The obvious way to do this is bitwise AND with 126 (or 254 etc), but it's shorter to set it to 1 (via bitwise OR with 1) instead and then decrement the result. Finally, we need to fix newlines manually:

"r"(  e# Push the string "r" and pull out the character.
(~    e# Decrement to q and eval to read input.
(     e# Pull out the character from the input string.
2(|(  e# (input OR (2-1))-1 == input AND 126
0$    e# Copy the result.
N&    e# Set intersection with a string containing a newline.
"~"   e# Push "~".
"@@"( e# Push "@@" and pull out one @.
(|    e# Decrement to ?, set union with the other string to give "@?".
~     e# Eval to select either the computed character or "~" if it was a newline.

Program B

(Outdated, will update tomorrow.)

This program can simply set the least significant bit to 1 via bitwise OR with 1 now. But it has to check for both \v (character code 0x0B) and <DEL> (character code 0xFF) manually and set them to ~ instead. In GolfScript I didn't have access to eval, but instead you can add a string to a block (which then becomes part of the code in that block), which I could map onto the input with %:

{1}    # Push this block without executing it.
'{--'  # Push this string.
{)}%   # Increment each character to get '|..'.
')1)7?=[11=+9)?ie'
       # Push another string...
7/     # Split it into chunks of 7: [')1)7?=[' '11=+9)?' 'ie']
{))}%  # For each chunk, split off the last character and increment it.
+      # Add the array to the string, flattening the array: '|..)1)7?=\11=+9)@if'
+      # Add it to the block: {1|..)1)7?=\11=+9)@if}
%      # Map the block onto the input, i.e. apply it to the single character.

And as for the generated code in the block:

1|..   # Bitwise OR with 1, make two copies.
)1)7?= # Check if the result is one less than 2^7 == 128 (i.e. if it's <DEL>).
\11=   # Check with the other copy if it's equal to 11 (i.e. if it's \v).
+      # Add them to get something truthy either way.
9)     # Push a 10 (i.e. \n).
@      # Pull up the original value.
if     # Select the correct result.

Martin Ender

Posted 2015-09-04T22:03:12.913

Reputation: 184 808

15

Java - 1088 bytes + Java - 1144 bytes = 2232 bytes

Thanks to @durron597 for helping to golf 1090 bytes from the first program.

Proof that it is possible to do in one language (and a non-esolang at that).

Use the unicode trick to convert the first one to all unicode characters. The second one uses reflection to get access to System.out in order to print to std. out. It couldn't use the u because that was used in the first program. I know this can be golfed more, but I wanted to post a valid solution first.

The groups are fairly arbitrarily mapped, but basically, the first one required only u,\, and the hexadecimal digits (in any case).

The groups:

!#7$&89'0123456>fB@UXZ\^AKCDEGH_JL`NOkQRxzVWYu~\n
 "%()*+,-./:;<=?FIMPST[]abcdeghijlmnopqrstvwy{|}

First program:

\u0076\u006F\u0069\u0064
k\u0028\u0069\u006E\u0074
x\u0029\u007B\u0069\u006E\u0074\u005B\u005Du\u003D\u007B33\u002C33\u002C35\u002C35\u002C36\u002C55\u002C38\u002C39\u002C36\u002C38\u002C56\u002C57\u002C39\u002C48\u002C49\u002C50\u002C48\u002C49\u002C50\u002C51\u002C52\u002C53\u002C54\u002C55\u002C56\u002C57\u002C51\u002C52\u002C53\u002C54\u002C62\u002C62\u002C64\u002C65\u002C66\u002C67\u002C68\u002C69\u002C102\u002C71\u002C72\u002C66\u002C74\u002C75\u002C76\u002C64\u002C78\u002C79\u002C85\u002C81\u002C82\u002C88\u002C90\u002C85\u002C86\u002C87\u002C88\u002C89\u002C90\u002C92\u002C92\u002C94\u002C94\u002C95\u002C96\u002C65\u002C75\u002C67\u002C68\u002C69\u002C102\u002C71\u002C72\u002C95\u002C74\u002C107\u002C76\u002C96\u002C78\u002C79\u002C107\u002C81\u002C82\u002C120\u002C122\u002C117\u002C86\u002C87\u002C120\u002C89\u002C122\u002C117\u002C126\u002C10\u002C126\u007D\u003B\u0053\u0079\u0073\u0074\u0065\u006D\u002E\u006Fu\u0074\u002E\u0070\u0072\u0069\u006E\u0074\u0028x>10\u003F\u0028\u0063\u0068\u0061\u0072\u0029u\u005Bx\u002D32\u005D\u003A'\u005C\u006E'\u0029\u003B\u007D

Equivalent to

void
k(int
x){int[]u={33,33,35,35,36,55,38,39,36,38,56,57,39,48,49,50,48,49,50,51,52,53,54,55,56,57,51,52,53,54,62,62,64,65,66,67,68,69,102,71,72,66,74,75,76,64,78,79,85,81,82,88,90,85,86,87,88,89,90,92,92,94,94,95,96,65,75,67,68,69,102,71,72,95,74,107,76,96,78,79,107,81,82,120,122,117,86,87,120,89,122,117,126,10,126};System.out.print(x>10?(char)u[x-32]:'\n');}

Second program:

void n(int r)throws Throwable{int p=(int)Math.PI;int q=p/p;int t=p*p+q;int w=q+q;int[]g={t*p+w,t*p+w,t*p+q+p,t*p+q+p,t*(q+p),t*p+t-p,t*(q+p)+q,t*(q+p)+q+p,t*(q+p),t*(q+p)+q,t*(q+p)+w,t*(q+p)+p,t*(q+p)+q+p,t*(q+p)+p+w,t*(q+p)+p+p,t*(q+p)+t-p,t*(q+p)+p+w,t*(q+p)+p+p,t*(q+p)+t-p,t*(p+w)+t-w,t*(p+w)+t-q,t*(p+p),t*(p+p)+q,t*p+t-p,t*(q+p)+w,t*(q+p)+p,t*(p+w)+t-w,t*(p+w)+t-q,t*(p+p),t*(p+p)+q,t*(p+p)+p,t*(p+p)+p,t*(t-p)+t-p,t*(t-q)+t-p,t*(t-p)+p,t*(t-q)+t-q,t*t,t*t+q,t*(t-p),t*t+p,t*t+q+p,t*(t-p)+p,t*t+p+p,t*(t-q)+t-w,t*t+t-w,t*(t-p)+t-p,t*(t+q),t*(t+q)+q,t*(t-w),t*(t+q)+p,t*(t+q)+q+p,t*(t-w)+p,t*(t-w)+q+p,t*(t-w),t*(t+q)+t-w,t*(t+q)+t-q,t*(t-w)+p,t*(t+w)+q,t*(t-w)+q+p,t*(t-q)+q,t*(t-q)+q,t*(t-q)+p,t*(t-q)+p,t*t+p+w,t*t+t-q,t*(t-q)+t-p,t*(t-q)+t-w,t*(t-q)+t-q,t*t,t*t+q,t*(t-p),t*t+p,t*t+q+p,t*t+p+w,t*t+p+p,t*(t+q)+w,t*t+t-w,t*t+t-q,t*(t+q),t*(t+q)+q,t*(t+q)+w,t*(t+q)+p,t*(t+q)+q+p,t*(t+q)+p+w,t*(t+q)+p+p,t*(t+w)+p,t*(t+q)+t-w,t*(t+q)+t-q,t*(t+q)+p+w,t*(t+w)+q,t*(t+q)+p+p,t*(t+w)+p,t*(t+w)+q+p,t*(t+w)+p+w,t*(t+w)+q+p};java.io.PrintStream o=(java.io.PrintStream)System.class.getFields()[p/p].get(p);o.print((r<=t)?"}":(char)g[r-t*p-w]);}

Try them out here: https://ideone.com/Q3gqmQ

bmarks

Posted 2015-09-04T22:03:12.913

Reputation: 2 114

There are no characters you can pull out of the first program that don't need to be unicode escaped? Can't you pull out some of the numbers? What if you did void x(int z), those are characters in the first charset too – durron597 – 2015-09-06T02:56:58.177

I'm sure it's possible. I could rename some variables and replace all spaces with new lines or tabs. I'll do that when I get home. I just wanted to prove a single language solution first. – bmarks – 2015-09-06T03:00:01.097

5

FIXED! Pyth - 23 bytes + Pyth - 30 bytes = 53 bytes

oops Fixing error --- please be patient

same ASCII split as Martin's:

1: "$&(*,.02468:<>@BDFHJLNPRTVXZ\^`bdfhjlnprtvxz|~
2:!#%')+-/13579;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}\n

Prog#1: Test Online

.xhft<zT.Dr\¡b:Z140 2\~

Prog#2: Test Online

C?%KCwy1K?qy5Ky5?qy+1y31Ky5+1K

Brian Tuck

Posted 2015-09-04T22:03:12.913

Reputation: 296