41
\$\begingroup\$

Introduction

While studying, I tried to come up with several ways to cheat a multiple choice test. It basically is a compressed version of the multiple choice answers. The method goes as following:

The answers to the test:

BCAABABA

These can be converted to 3 different arrays, which indicates true or false if the current letter is the answer:

    B  C  A  A  B  A  B  A
A: [0, 0, 1, 1, 0, 1, 0, 1]
B: [1, 0, 0, 0, 1, 0, 1, 0]
C: [0, 1, 0, 0, 0, 0, 0, 0]

Interpreting these numbers as binary would compress this a lot. But this can actually be compressed a bit more. If you know the positions of A and B, you don't need the positions for C. This can be done with a bitwise NOT operator:

A: [0, 0, 1, 1, 0, 1, 0, 1]
B: [1, 0, 0, 0, 1, 0, 1, 0]

A+B: [1, 0, 1, 1, 1, 1, 1, 1]
C:   [0, 1, 0, 0, 0, 0, 0, 0]

Converting the arrays A and B to binary numbers would result in:

A: 00110101
B: 10001010

That means that 8 multiple choice answers can be compressed to two bytes!


Task

Given two numbers in binary, or two arrays consisting of only 0's and 1's with the same length, output the multiple choice answers


Rules

  • Input can be in the any form you like, like [1, 0, 0, 1] or 1001.
  • You may provide a program or a function.
  • You may assume that the input is always valid.
  • You may also output as a list, separated with spaces, etc.
  • The multiple choice answers only consist of A's, B's and C's. You may however use lower case instead.
  • This is , so the submission with the least amount of bytes wins!

Test cases

Input: [1, 0, 0, 1, 0, 0, 1] [0, 1, 0, 0, 1, 0, 0]
Output: ABCABCA

Input: [0, 0, 0, 0, 1, 0, 1, 1] [1, 0, 1, 0, 0, 0, 0, 0]
Output: BCBCACAA

Input: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Output: CCCCCCCCCC

Leaderboard

var QUESTION_ID=69770,OVERRIDE_USER=34388;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important;font-family:Arial}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

\$\endgroup\$
15
  • 79
    \$\begingroup\$ Here is my solution. It is written in English (interpreter freely available wherever you are), and is Study.. Six bytes. Beat that. \$\endgroup\$ Jan 20, 2016 at 19:01
  • 60
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Sadly, English does not meet our standards of a programming language and is therefore not a valid submission :p \$\endgroup\$
    – Adnan
    Jan 20, 2016 at 19:05
  • 18
    \$\begingroup\$ You can actually compress eight multiple choice questions to 1.625 bytes (13 bits) by interpreting the answers as base 3, so technically this isn't the most efficient method. :P \$\endgroup\$
    – Doorknob
    Jan 20, 2016 at 23:29
  • 4
    \$\begingroup\$ You could add another answer in the same space by using all four combinations of two bits, 00, 01, 10, 11 for answer a, b, c or d. You are not using 11. \$\endgroup\$ Jan 21, 2016 at 9:23
  • 6
    \$\begingroup\$ English satisfies all the criteria. The only problem is there isn't an interpreter available before this question is asked. \$\endgroup\$
    – jimmy23013
    Jan 22, 2016 at 2:06

34 Answers 34

50
\$\begingroup\$

Jelly, 7 6 bytes

_/ị“ḃ»

Typing on phone. Will add description.

(1,0) goes to A, (0,1) to B, and (0,0) to C. Arrays in Jelly are 1-based, and the indexing function works cyclically. Therefore, we can just fold subtraction over the input.

_              [vectorized] subtraction
_/             Fold subtraction over the input
   “ḃ»         "ABC" compressed. '»' terminates a compressed string.
  ị            Vectorized cyclic index.

Try it here.

\$\endgroup\$
10
  • 55
    \$\begingroup\$ how on earth did you type that on a phone? o-O \$\endgroup\$ Jan 20, 2016 at 19:41
  • 35
    \$\begingroup\$ Samsung's clipboard history. It wasn't easy. \$\endgroup\$
    – lirtosiast
    Jan 20, 2016 at 19:45
  • 10
    \$\begingroup\$ :-DD And congrats on 10k! \$\endgroup\$
    – Luis Mendo
    Jan 20, 2016 at 19:55
  • 8
    \$\begingroup\$ Lol, same size as English now @CᴏɴᴏʀO'Bʀɪᴇɴ \$\endgroup\$
    – RK.
    Jan 20, 2016 at 21:31
  • 14
    \$\begingroup\$ I golf my answer to "Study"; I am using an interpreter that is okay with grammatical mistakes. @RK. \$\endgroup\$ Jan 20, 2016 at 21:56
11
\$\begingroup\$

J, 8 bytes

'CAB'{~-

Usage:

   0 0 1 0 0 1 ('CAB'{~-) 0 1 0 1 0 0
CBABCA

Try it online here.

\$\endgroup\$
11
\$\begingroup\$

Retina, 44 bytes

T`d`BA
B(?=(.)* .*B(?<-1>.)*(?(1)!)$)
C
 .+

The trailing linefeed is significant. Input is like

001101010 100010100

Try it online!

Explanation

T`d`BA

Start by turning 0s into B and 1s into A. That makes the first half correct, except that it lists B when it should contain C. We can identify those erroneous Bs by checking whether there's a B in the same position of the second string:

B(?=(.)* .*B(?<-1>.)*(?(1)!)$)
C

The lookahead is a classic balancing group counting technique to match up the positions of the two Bs. The (.)* counts the suffix after the first B by pushing one capture onto group 1 for each character. Then (?<-1>.)* pops from that group again. The $ ensures that we can reach the end of the string like that, and the (?(1)!) ensures that we've actually depleted the entire group.

Finally, we get rid of the separating space and the second string:

 .+

\$\endgroup\$
3
  • 1
    \$\begingroup\$ 3 upvotes in the first 15 seconds of posting; that must be some kind of record. \$\endgroup\$ Jan 20, 2016 at 20:00
  • 8
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Flattering, but I wonder how many of those 3 upvoters actually read and understood the answer in 15 seconds. :/ \$\endgroup\$ Jan 20, 2016 at 20:01
  • 4
    \$\begingroup\$ I did. I am rather fluent in reading regex and retina. \$\endgroup\$ Jan 20, 2016 at 20:04
11
\$\begingroup\$

Java, 81 bytes

No reputation to comment the already existing Java solution, so here goes:

void x(int[]a,int[]b){int j=0;for(int i:a)System.out.printf("%c",67-2*i-b[j++]);}
\$\endgroup\$
2
  • 1
    \$\begingroup\$ This is smart. :D I like. I see that you got a teensy bit of inspiration, though. ;) \$\endgroup\$ Jan 22, 2016 at 23:38
  • 1
    \$\begingroup\$ Damn, that's clever. I spent ages trying to figure out how I could get a foreach loop to fit... \$\endgroup\$
    – CameronD17
    Jan 23, 2016 at 14:00
11
\$\begingroup\$

MATL, 14 9 bytes

2*+ 67w-c

Uses current version (10.1.0)

Try it online!

Explanation

Summary of what the code does

2*       % implicitly input array and multiply it by 2
+        % implicitly input array and add it to the first one
67w-    % subtract from 67
c        % convert to char. Implicitly display

Detailed explanation of how it works

2        % Push number 2 onto the stack
*        % Multiply the top two stack elements. Since there's only one
         % element, this triggers implicit input of a (yet inexistent)
         % element below the existing one. This is the first input array,
         % which will be called "A". Both "A" and number 2 are consumed,
         % and the array 2*A is left on the stack.
+        % Add the top two stack elements. Again, since there's only
         % one element (namely array 2*A) this triggers implicit input
         % of the second array, call it "B". Both 2*A and B are consumed
         % and 2*A+B is left on the stack
         % A blank space is needed after the "+" symbol to prevent it from
         % being interpreted as part of number "+67"
67       % Push number 67 onto the stack. The stack now contains, bottom
         % to top, 2*A+B and 67.
w        % Swap top two elements. The stack now contains 67 and 2*A+B
-        % Subtract top two elements. These are consumed and the result
         % 67-A*B is left on the stack
c        % Convert to char array, interpreting each number as ASCII code.
         % Number 67 corresponds to letter 'C'. Therefore at positions
         % where both arrays A and B were 0 this gives 'C' as result.
         % Where A was 1 and B was 0, i.e. 2*A+B is 2, this gives 'A'.
         % Where A was 0 and B was 1, i.e. 2*A+B is 1, this gives 'B'.
         % The stack contents, namely this char array, are implicitly
         % displayed at the end of the program.
\$\endgroup\$
3
  • \$\begingroup\$ This is amazing! Can you write a bit more about why this works? Why 67? And how does multiply input array by 2 and then add input array differ from 'multiply input array by 3'? \$\endgroup\$
    – Vincent
    Jan 22, 2016 at 9:22
  • 1
    \$\begingroup\$ @Vincent Sure! I'll add some more detailed explanation later in the day \$\endgroup\$
    – Luis Mendo
    Jan 22, 2016 at 9:44
  • \$\begingroup\$ @Vincent Done! Let me know if it's clearer now \$\endgroup\$
    – Luis Mendo
    Jan 22, 2016 at 22:39
10
\$\begingroup\$

JavaScript ES6, 36 bytes

(a,b)=>a.map((x,y)=>"CBA"[x*2+b[y]])

Very simple, and probably obvious enough to understand: Map each item and index in a to the char at position (x*2 + item at index y in b) in "CBA".

\$\endgroup\$
3
  • 7
    \$\begingroup\$ Please add this as your ungolfed version :3 \$\endgroup\$ Jan 20, 2016 at 19:45
  • 2
    \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ He CBA to do that. Also, he can't anyway, because do is a reserved keyword, so that's invalid syntax. \$\endgroup\$ Jan 21, 2016 at 15:49
  • \$\begingroup\$ @Patrick simple fix: Do(...) \$\endgroup\$ Jan 21, 2016 at 19:09
9
\$\begingroup\$

brainfuck, 52 bytes

,+[->>----[<--->----],+]<[<[>--<-]<]>>[<,[>-<-]>.>>]

Requires an interpreter that lets you go left from cell 0 and has 8-bit wrapping cells. Unlike most of my answers, EOF behaviour doesn't matter.

Takes byte input, with 0xFF as a delimiter. A stream of bytes representing the first input under "Test cases" would look like this:

0x01 0x00 0x00 0x01 0x00 0x00 0x01 0xFF 0x00 0x01 0x00 0x00 0x01 0x00 0x00

I could save a couple bytes by having 0x00 as a delimiter and using 0x01 and 0x02 as 0 and 1 respectively, but that felt like cheating :P

Once I figured out my strategy, writing this program was very easy. To find the nth letter to output, start with 0x43 (capital C in ASCII) and subtract ((nth element of first sequence)*2 + nth element of second sequence)

For what it's worth, here's the 52 byte program split into 3 lines and with some words beside them:

Get input until hitting a 255 byte; put a 67 byte to the right of each one
,+[->>----[<--->----],+]

For each 67 byte: Subtract (value to the left)*2 from it
<[<[>--<-]<]

For each byte that used to contain 67: Subtract input and print result
>>[<,[>-<-]>.>>]
\$\endgroup\$
9
\$\begingroup\$

Haskell, 29 bytes

zipWith(\x y->"BCA"!!(x-y+1))

An anonymous function. Use like:

>> zipWith(\x y->"BCA"!!(x-y+1)) [1, 0, 0, 1, 0, 0, 1] [0, 1, 0, 0, 1, 0, 0]
"ABCABCA"

I tried making the function point-free but got a total mess. 2022 edit: Wheat Wizard found a version for 28 bytes, one shorter than nimi's 29-byte equivalent:

zipWith$(!!).(["CB","AC"]!!)
\$\endgroup\$
2
  • 6
    \$\begingroup\$ a point-free version of equal length: zipWith((!!).(["CB","AC"]!!)) \$\endgroup\$
    – nimi
    Jan 21, 2016 at 14:29
  • \$\begingroup\$ A point-free version that's 1 byte shorter zipWith$(!!).(["CB","AC"]!!). \$\endgroup\$
    – Wheat Wizard
    Jun 25, 2022 at 22:05
8
\$\begingroup\$

Pyth, 18 16 10 bytes

3rd attempt: 10 bytes

Thank FryAmTheEggman for reminding me of the existence of G!

VCQ@<G3xN1

Input is of the form [ [0,0,1,1,0,1,0,1] , [1,0,0,0,1,0,1,0] ], which is essentially a matrix: row for choice and column for question number.

Hand-compiled pythonic pseudocode:

              G = "abcdefghijklmnopqrstuvwxyz"    // preinitialized var
VCQ           for N in transpose(Q):    // implicit N as var; C transposes 2D lists
   @<G3           G[:3][                // G[:3] gives me "abc"
       xN1            N.index(1)        // returns -1 if no such element
                  ]

2nd attempt: 16 bytes

VCQ?hN\A?.)N\B\C

Input is of the form [ [0,0,1,1,0,1,0,1] , [1,0,0,0,1,0,1,0] ], which is essentially a matrix: row for choice and column for question number.

This compiles to

assign('Q',Pliteral_eval(input()))
for N in num_to_range(Pchr(Q)):
   imp_print(("A" if head(N) else ("B" if N.pop() else "C")))

Ok, I know that looks messy, so let's hand-compile to pythonic pseudocode

                 Q = eval(input())
VCQ              for N in range transpose(Q): // implicit N as var; transposes 2D lists
   ?hN               if head(N):              // head(N)=1st element of N
      \A                 print("A")           // implicit print for expressions
                     else:
        ?.)N             if pop(N):
            \B               print("B")
                         else:
              \C             print("C")

1st attempt: 18 bytes

V8?@QN\A?@Q+8N\B\C

With input of the form [0,0,1,1,0,1,0,1,1,0,0,0,1,0,1,0], essentially concatenation of two lists. This compiles to

assign('Q',Pliteral_eval(input()))
for N in num_to_range(8):
   imp_print(("A" if lookup(Q,N) else ("B" if lookup(Q,plus(8,N)) else "C")))

Again, compiling by hand

                   Q = eval(input())
V8                 for N in range(8):
  ?@QN                 if Q[N]:
      \A                  print("A")
                       else:
        ?@Q+8N            if Q[N+8]:
              \B              print("B")
                          else:
                \C            print("C")

And there goes the first codegolf in my life!!! I just learned Pyth yesterday, and this is the first time I ever participated in a code golf.

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to Programming Puzzles and Code Golf! This looks very nice for a first time, +1 \$\endgroup\$
    – Adnan
    Jan 21, 2016 at 13:52
  • \$\begingroup\$ Always nice to see someone learning Pyth! You can golf .) to be e, and I think it can be golfed quite a bit more. Consider the variable G which contains the lower case alphabet, I believe you can get to around 10 bytes using it, happy golfing! :) \$\endgroup\$ Jan 21, 2016 at 14:03
  • \$\begingroup\$ @FryAmTheEggman oh e! I was searching for it for several minutes! Also, thank you for reminding me of G. You are right, 10 bytes! \$\endgroup\$
    – busukxuan
    Jan 21, 2016 at 14:38
7
\$\begingroup\$

Python 3, 39 bytes.

Saved 1 byte thanks to FryAmTheEggman.
Saved 2 bytes thanks to histocrat.

Haven't been able to solve with a one liner in a while!

lambda*x:['CBA'[b-a]for a,b in zip(*x)]

Here's my test cases. It also shows the way I'm assuming this function is called.

assert f([1,0,0,1,0,0,1], [0,1,0,0,1,0,0]) == ['A', 'B', 'C', 'A', 'B', 'C', 'A']
assert f([0, 0, 0, 0, 1, 0, 1, 1], [1, 0, 1, 0, 0, 0, 0, 0]) == ['B', 'C', 'B', 'C', 'A', 'C', 'A', 'A']
assert f([0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) == ['C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C']

It uses zip to iterate through the arrays pairwise, and then indexes into a string to pick the correct letter. This all happens in a list comprehension, so it automagically becomes a list. The core of this solution is that the only possible combinations of a and b are [0, 1], [1, 0], [0, 0]. So if we subtract them, we get one of -1, 0, 1 which gets us the last, first, middle element respectively.

\$\endgroup\$
0
7
\$\begingroup\$

Mathematica, 30 24 22 19 bytes

3 bytes saved due to @alephalpha.

{A,B,C}[[3-2#-#2]]&

Quite simple.

\$\endgroup\$
1
  • \$\begingroup\$ {A,B,C}[[3-2#-#2]]& \$\endgroup\$
    – alephalpha
    Aug 27, 2016 at 14:34
5
\$\begingroup\$

Ruby, 35 bytes

->a,b{a.zip(b).map{|x,y|:CAB[x-y]}}

Usage:

->a,b{a.zip(b).map{|x,y|:CAB[x-y]}}[[1,0,0],[0,1,0]]
=> ["A", "B", "C"]

Takes the (x-y)th zero-indexed character of "CAB". (1-0) gives 1, and thus A. (0-0) gives 0, and thus C. (0-1) gives -1, which wraps around to B.

Alternate shorter solution with weirder output:

->a,b{a.zip(b){|x,y|p :CAB[x-y]}}

Output is quoted strings separated by newlines, which seems a bridge too far somehow.

\$\endgroup\$
4
\$\begingroup\$

Japt, 13 bytes

¡#C-X*2-VgY)d

Try it online!

How it works

¡#C-X*2-VgY)d  // Implicit: U, V = input lists
¡              // Map each item X and index Y in U to:
 #C-X*2        //  The char code of C (67), minus 2X,
       -VgY)   //  minus the item at index Y in V.
            d  //  Convert to a char code.
\$\endgroup\$
4
\$\begingroup\$

Octave, 19 bytes

@(x,y)[67-y-2*x,'']

Test:

f([1 0 0 0 1 1],[0 1 0 0 0 0])
ans = ABCCAA

I'll add an explanation later when I have a computer in front of me. This was written and tested on octave-online on my cell.

\$\endgroup\$
4
\$\begingroup\$

TI-BASIC, 59 57 50 37 36 bytes

Takes one list from Ans, and the other from Prompt L₁. Saved 13 bytes thanks to Thomas Kwa's suggestion to switch from branching to sub(.

Prompt X
For(A,1,dim(∟X
Disp sub("ACB",2+∟X(A)-Ans(A),1
End

I'll have to look for what Thomas Kwa said he found in the comments tomorrow. ¯\_(ツ)_/¯

\$\endgroup\$
5
  • \$\begingroup\$ You still have some bytes to save! Replace the Prompt L₁ with Prompt X and L₁ with ∟X. There's even more, but I'll let you find it. \$\endgroup\$
    – lirtosiast
    Jan 21, 2016 at 3:20
  • \$\begingroup\$ @ThomasKwa L1 is a one-byte token, last I checked. Referencing it again with the list+x would be two bytes... am I not correct? \$\endgroup\$ Jan 21, 2016 at 3:36
  • \$\begingroup\$ L1 is two bytes. \$\endgroup\$
    – lirtosiast
    Jan 21, 2016 at 3:56
  • \$\begingroup\$ @ThomasKwa Oh. Dang. \$\endgroup\$ Jan 21, 2016 at 3:57
  • \$\begingroup\$ I count 37 bytes as it is currently. (You can get 35.) \$\endgroup\$
    – lirtosiast
    Jan 22, 2016 at 18:11
4
\$\begingroup\$

Rust, 79

Saved 8 bytes thanks to Shepmaster.
Saved 23 bytes thanks to ker.

I'm positive this could be golfed down a lot, but this is my first time writing a full Rust program.

fn b(a:&[&[u8]])->Vec<u8>{a[0].iter().zip(a[1]).map(|(c,d)|67-d-c*2).collect()}

Here's the ungolfed code and test cases in case anyone wants to try to shrink it.

fn b(a:&[&[u8]])->Vec<u8>{
    a[0].iter().zip(a[1]).map(|(c,d)|67-d-c*2).collect()
}
fn main() {
    assert_eq!("ABCABCA", b(&[&[1, 0, 0, 1, 0, 0, 1], &[0, 1, 0, 0, 1, 0, 0]]));
    assert_eq!("BCBCACAA", b(&[&[0, 0, 0, 0, 1, 0, 1, 1], &[1, 0, 1, 0, 0, 0, 0, 0]]));
    assert_eq!("CCCCCCCCCC", b(&[&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]));
}

The approach is pretty similar to my Python answer. The main difference being that I can't directly index strings, so I can't do the c-d trick.

\$\endgroup\$
5
  • \$\begingroup\$ would it be legal to use a closure instead of a function? then you could skip all the types in the declaration and just pass a[0] and a[1] as two separate arguments. \$\endgroup\$
    – oli_obk
    Jan 22, 2016 at 8:21
  • \$\begingroup\$ also using the 64-y-2*x trick from the Octave solution saves quite a few bytes due to being able to use u8 instead of usize: is.gd/GNPK76 \$\endgroup\$
    – oli_obk
    Jan 22, 2016 at 8:28
  • \$\begingroup\$ @ker I'm not totally sure about using a closure. I would assume it's okay, because it's essentially an anonymous function, right? \$\endgroup\$ Jan 22, 2016 at 14:11
  • \$\begingroup\$ as long as you don't capture any surroundings it's exactly like an anonymous function. \$\endgroup\$
    – oli_obk
    Jan 22, 2016 at 15:18
  • \$\begingroup\$ @ker Then yeah, closure should be fine. \$\endgroup\$ Jan 22, 2016 at 15:28
4
\$\begingroup\$

Vitsy, 40 bytes

sigh My baby was not made to do array manipulation.

Expects input through STDIN (something I never do) with a leading ".

WX&WXl\[68*-1+m]
?68*-2*"C"-i*O?
"B"O?X?

Explanation in the (soon available) verbose mode:

0:
STDIN;
remove top;
make new stack;
STDIN;
remove top;
push length of stack;
repeat next instruction set top times;
begin recursive area;
push 6;
push 8;
multiply top two;
subtract top two;
push 1;
add top two;
goto top method;
end recursive area;
1:
rotate right a stack;
push 6;
push 8;
multiply top two;
subtract top two;
push 2;
multiply top two;
toggle quote;
push cosine of top; // this is character literal "C"
toggle quote;
subtract top two;
push input item;
multiply top two;
output top as character;
rotate right a stack;
2:
toggle quote;
B;
toggle quote;
output top as character;
rotate right a stack;
remove top;
rotate right a stack;

This is getting golfed better real soon, people. I'm so sorry for its current length.

Basically, I treat the input as a string, and then manipulate from there.

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ :O Cannot wait until verbose mode. That will be interesting. Like the use of W! \$\endgroup\$ Jan 23, 2016 at 4:01
  • \$\begingroup\$ @Adnan It is the input tab in tryitonline, but on the local interpreter, simply run the program and input each set of 0 and 1 with a leading " and a trailing newline while the program is running (W technically is prompt). \$\endgroup\$ Jan 23, 2016 at 14:08
  • \$\begingroup\$ Ahh, I gave the input in the arguments section :p. Nice answer though :) \$\endgroup\$
    – Adnan
    Jan 23, 2016 at 14:10
  • \$\begingroup\$ @Adnan It took me a while to figure this out - Vitsy autoparses input if it recognizes that it's a double. You can technically have a leading anything except for numbers, and it'll work the same. \$\endgroup\$ Jan 23, 2016 at 14:12
  • \$\begingroup\$ Heh, that is quite weird, but on the other side it can be useful. \$\endgroup\$
    – Adnan
    Jan 23, 2016 at 14:33
3
\$\begingroup\$

CJam, 10 bytes

'Cq~z2fbf-

Input as a list of two lists, e.g.

[[1 0 0 1 0 0 1] [0 1 0 0 1 0 0]]

Test it here.

Explanation

Treating the pairs as bits of a base-2 number, we get 2 for A, 1 for B and 0 for C.

'C  e# Push the character C.
q~  e# Read and evaluate input.
z   e# Transpose the pair of lists to get a list of pairs.
2fb e# Convert each pair from base 2.
f-  e# Subtract each result from the character C.
\$\endgroup\$
3
\$\begingroup\$

Python 3, 48 45 bytes

I thought I had an elegant solution, then I saw @Morgan Thrapp's answer...

edit: Saved three bytes thanks to the aforementioned.

lambda*x:['A'*a+b*'B'or'C'for a,b in zip(*x)]

lambda *x:[a*'A'or b*'B'or'C'for a,b in zip(*x)]

\$\endgroup\$
1
  • \$\begingroup\$ Ah nice. Didn't see lamba*x:. I always think it's as compact as can be then I get told/find even more tricks. I really like your solution btw, very nice. \$\endgroup\$
    – Ogaday
    Jan 22, 2016 at 17:44
3
\$\begingroup\$

Java, 131 122 110 90 bytes

EDIT: Thanks to Bifz / FlagAsSpam for the help and inspiration

void x(int[]a,int[]b){int j=0;for(int i:a){System.out.print(i>0?"A":b[j]>0?"B":"C");j++;}}

First submission, naive Java solution. Can almost certainly be improved :)

static String x(int[]a,int[]b){String o="";for(int i=0;i<a.length;i++)o+=a[i]>0?"A":b[i]>0?"B":"C";return(o);} 

\$\endgroup\$
3
  • \$\begingroup\$ ==1 can be >0; it would also be better for you to return o rather than printing. \$\endgroup\$
    – lirtosiast
    Jan 22, 2016 at 0:47
  • \$\begingroup\$ How about: void x(int[]a,int[]b){for(int i=0;i<a.length;i++)System.out.print(a[i]>0?"A":b[i]>0?"B":"C");} (94 bytes)? You don't need the static declaration on functions. \$\endgroup\$ Jan 22, 2016 at 23:07
  • \$\begingroup\$ You have to declare i first, +4 bytes :D \$\endgroup\$
    – Bifz
    Jan 23, 2016 at 23:20
3
\$\begingroup\$

R 29 16 bytes

LETTERS[3-2*A-B]

removed declaration of function since I saw it's common in other contests.

\$\endgroup\$
2
\$\begingroup\$

PowerShell, 40 Bytes

param($a,$b)$a|%{"CBA"[2*$_+$b[++$d-1]]}

Takes input as two explicit arrays, e.g.. PS C:\Tools\Scripts\golfing> .\cheating-a-multiple-choice-test.ps1 @(1,0,0,1,0,0,1) @(0,1,0,0,1,0,0), and stores them in $a and $b. Next, loop through $a with $a|{...}. Each loop, we output a character indexed into the string "CBA", with the index decided by twice the current value $_, plus the value of $b indexed by our helper variable that's been pre-added then subtracted.

As an example, for the first test case, $a = @(1,0,0,1,0,0,1) and $b = @(0,1,0,0,1,0,0). The first loop iteration has $_ = 1, $d = $null (since $d hasn't previously been declared). We pre-add to $d so now $_ = 1 and $d = 1 (in PowerShell, $null + 1 = 1), meaning that $b[1-1] = $b[0] = 0. Then 2 * 1 + 0 = 2, so we index "CBA"[2], or A.

\$\endgroup\$
2
\$\begingroup\$

𝔼𝕊𝕄𝕚𝕟, 12 chars / 22 bytes

Ⓒ…îⓜṃ-$*2-í_

Try it here (Firefox only).

Explanation

Translates to Javascript ES6 as

String.fromCharCode(...input1.map(($,_)=>67-$*2-input2[_]))
\$\endgroup\$
2
\$\begingroup\$

R 36 34 bytes

function(a,b)c('B','C','A')[a-b+2]

Two bytes saved removing unnecessary braces

\$\endgroup\$
1
  • \$\begingroup\$ You can save two bytes by removing the braces in the function definition. They aren't necessary since the function body consists of a single statement. \$\endgroup\$
    – Alex A.
    Jan 22, 2016 at 0:33
2
\$\begingroup\$

Perl 5 - 47

Already 30 answers and no perl? Here is a naive first attempt then :-) Just the function:

sub x{($g,$h)=@_;map{$_?a:$h->[$i++]?b:c}@{$g}}

Usage:

@f = (0, 0, 0, 0, 1, 0, 1, 1);
@s = (1, 0, 1, 0, 0, 0, 0, 0);

print x(\@f, \@s);

I'm pretty sure that something better could be done with regex, but I couldn't find how.

\$\endgroup\$
1
\$\begingroup\$

JavaScript ES6, 75 bytes

I went the extra mile to accept integer arguments instead of array arguments.

(a,b)=>[...Array(8)].map((_,n)=>'CBA'[(a&(s=128>>n)*2+b&s)/s]).join('')

Explanation:

(a,b)=>              // input of two integers representing 8 answers (max value 255 each)
[...Array(8)]        // generates an array with 8 indices that allows .map() to work
.map((_,n)=>         // n is each index 0-7
'CBA'[...]           // reading character from string via index reference
      (...)          // grouping for division
       (a&...)       // AND operator to test if answer is A
          (s=128>>n) // calculating binary index in integer input and storing reference
       *2            // bias index in 'CBA' so truthy is 2 instead of 1
       +(b&s)        // AND operator to test if answer is B
      /s             // divide by binary index to convert AND operators to increments of 1
.join('')            // convert to string without commas

Credit to @ETHproductions for string indexing logic.

Test Here

f=(a,b)=>[...Array(8)].map((_,n)=>'CBA'[((a&(s=128>>n))*2+(b&s))/s]).join('');

console.log(f(0b01001001, 0b00100100));
console.log(f(0b00001011, 0b10100000));
console.log(f(0b00000000, 0b00000000));
<!-- results pane console output; see http://meta.stackexchange.com/a/242491 -->
<script src="http://gh-canon.github.io/stack-snippet-console/console.min.js"></script>

Pssst

For 3 extra bytes, it can display the representation for up to 30 answers:

(a,b)=>[...Array(30)].map((_,n)=>'CBA'[((a&(s=1<<30>>n))*2+(b&s))/s]).join('')
\$\endgroup\$
1
\$\begingroup\$

Retina, 46 bytes

^
%
+`%(.)(.* )(.)
$1$3,%$2
10
A
01
B
00
C
\W
[empty line]

Merges the two strings and chooses the letters according to the digit pairs.

Try it online here.

\$\endgroup\$
1
\$\begingroup\$

Lua, 87 Bytes

Simply testing the values in the arrays, and concatenating A, B or C.

function f(a,b)s=""for i=1,#a do s=s..(0<a[i]and"A"or 0<b[i]and"B"or"C")end print(s)end
\$\endgroup\$
1
\$\begingroup\$

F#, 33 bytes

Seq.map2(fun a b->67-a*2-b|>char)

That's a partially applied function that takes two int sequences - two arrays work fine - and returns a new sequence of characters representing the correct answers. =)

\$\endgroup\$
1
\$\begingroup\$

Seriously, 14 bytes

,,Z`i-"CBA"E`M

Try It Online

Probably due to a bug in the safe mode version of the interpreter, you must add an X to get it to work right in the online version. Download the local version to get the above program working correctly as-is.

It's too short to warrant a full explanation, so I'll just say: it uses the same algorithm as the Jelly answer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.