26
\$\begingroup\$

This is a CMC (chat mini challenge) that I posted in our chatroom, The Ninteenth Byte, a bit ago.

The Challenge

Given a positive integer x, depending on the last 2 bits of x, do the following:

x & 3 == 0: 0
x & 3 == 1: x + x
x & 3 == 2: x * x
x & 3 == 3: x ^ x (exponentiation)

Input/Output

Single Integer -> Single Integer  

A trailing newline is permitted in the output. No other whitespace is permitted.

Testcases

input       output
    1            2
    2            4
    3           27
    4            0
    5           10
    6           36
    7       823543
    8            0
    9           18
   10          100
   11 285311670611
   12            0

This is a challenge, so the shortest code wins!

\$\endgroup\$
  • 8
    \$\begingroup\$ Shouldn't the 0 case be x + 2, seeing as how the others are x * 2, x ^ 2, and x ^^ 2 (tetration)? :P \$\endgroup\$ – ETHproductions May 1 '17 at 13:47
  • \$\begingroup\$ What is the largest output we should support (regarding x ^ x)? 32-bit is already not enough for test case 11, and 64-bit is not enough for test case 19. \$\endgroup\$ – Kevin Cruijssen May 1 '17 at 14:23
  • \$\begingroup\$ @KevinCruijssen I will say that you only have to handle cases where the input and output are in the scope of your language, as long as your program would theoretically work given infinite number size. \$\endgroup\$ – HyperNeutrino May 1 '17 at 14:28
  • \$\begingroup\$ @HyperNeutrino Ok, in that case I've fixed my (Java 7) code (for +72 bytes.. xD) \$\endgroup\$ – Kevin Cruijssen May 1 '17 at 14:42

38 Answers 38

13
\$\begingroup\$

Jelly, 8 bytes

ị“+×*_”v

Try it online!

How it works

Firstly, notice that x&3 is equivalent to x%4, where % is modulo. Then, since Jelly uses modular indexing (a[n] == a[n+len(a)]), so we don't even need to deal with that.

Then:

  • If x%4==0, return x_x (subtraction) (for consistency);
  • If x%4==1, return x+x;
  • If x%4==2, return x×x(multiplication);
  • If x%4==3, return x*x(exponentiation)

Note that Jelly uses 1-indexing, so the subtraction "_" is moved to the end.

ị“+×*_”v  example input: 10
ị“+×*_”   index 10 of the string “+×*_”, which gives "×"
       v  evaluate the above as a Jelly expression,
          with 10 as the argument, meaning "10×" is the
          expression evaluated. The dyad "×" takes the
          second argument from the only argument, effectively
          performing the function to itself.
\$\endgroup\$
  • 2
    \$\begingroup\$ @andrybak AFAIK Jelly has its own encoding - see here, but I do know that all of its characters are 1 byte. \$\endgroup\$ – Stephen May 1 '17 at 22:57
  • \$\begingroup\$ "8 bytes". How should bytes be counted? This answer consists of eight characters, but at least in the encoding stackexchange serves this page, it takes up 15 bytes (counted using wc --bytes). \$\endgroup\$ – andrybak May 1 '17 at 22:58
  • \$\begingroup\$ If the language interprets it in one encoding, it doesn't make sense to use another encoding for the byte count (imo) \$\endgroup\$ – Mackenzie McClane May 2 '17 at 4:11
  • \$\begingroup\$ @andrybak The code encoded in an encoding so that the browser shows it correctly is 15 bytes. The code in an encoding that Jelly understands it is 8 bytes. Look at github.com/DennisMitchell/jelly/wiki/Code-page if you want to know how it is encoded. \$\endgroup\$ – Etoplay May 2 '17 at 12:27
13
\$\begingroup\$

Python, 30 bytes

lambda x:[0,x+x,x*x,x**x][x%4]

Try it online!

\$\endgroup\$
  • 2
    \$\begingroup\$ Alternative version on python 2: 'lambda x:[0,2,x,x**x/x][x%4]*x'. \$\endgroup\$ – TLW May 2 '17 at 2:51
9
\$\begingroup\$

CJam, 12 bytes

ri__"-+*#"=~

Try it online!

Explanation

ri            e# Read an int from input (call it x).
  __          e# Duplicate x twice.
    "-+*#"    e# Push this string.
          =   e# Get the character from the string at index x (mod 4).
           ~  e# Eval that char, using the two copies of x from before.

Runs one of the following operations depending on x's value mod 4 (mod 4 is equivalent to AND 3).

0:  -  Subtraction
1:  +  Addition
2:  *  Multiplication
3:  #  Exponentiation
\$\endgroup\$
6
\$\begingroup\$

Mathematica 25 Bytes

0[2#,#*#,#^#][[#~Mod~4]]&

Saved 4 Bytes thanks to @MartinEnder

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

Pyth, 8 bytes

.v@"0y*^

Interpreter

\$\endgroup\$
  • \$\begingroup\$ Yes I have tested this and it works. And no, I can't use v instead of .v. \$\endgroup\$ – Erik the Outgolfer May 1 '17 at 16:28
  • \$\begingroup\$ I thought the scope was local... I thought .v cannot access Q... Apparently I got outgolfed in Pyth. +1 for you. \$\endgroup\$ – Leaky Nun May 1 '17 at 16:33
  • \$\begingroup\$ @LeakyNun No it's v which has local scope, .v just evals an expression. \$\endgroup\$ – Erik the Outgolfer May 1 '17 at 16:34
  • \$\begingroup\$ I have much to learn... \$\endgroup\$ – Leaky Nun May 1 '17 at 16:35
  • 3
    \$\begingroup\$ That's beautiful! That's absolutely amazing! I had no idea that was even possible. For style points, "0y*^ could be "-+*^. \$\endgroup\$ – isaacg May 1 '17 at 17:07
4
\$\begingroup\$

Ruby, 26 bytes

->x{x*[0,2,x,x**~-x][x%4]}

Try it online!

\$\endgroup\$
3
\$\begingroup\$

PHP, 37 Bytes

<?=[0,2*$x=$argn,$x*$x,$x**$x][$x&3];

Online Version

PHP, 47 Bytes

<?=(bc.[sub,add,mul,pow][($x=$argn)&3])($x,$x);

Online Version

BC Math functions

\$\endgroup\$
3
\$\begingroup\$

Haskell, 28 27 bytes

f x=cycle[0,x+x,x*x,x^x]!!x

Try it online!

Edit: Thanks to @Ørjan Johansen for 1 byte.

\$\endgroup\$
  • \$\begingroup\$ Hm I'm very late, but you could shorten this a byte with cycle. \$\endgroup\$ – Ørjan Johansen Jun 24 '17 at 0:32
  • \$\begingroup\$ @ØrjanJohansen: better late than never. Thanks! \$\endgroup\$ – nimi Jun 24 '17 at 8:42
2
\$\begingroup\$

JavaScript, 24 bytes

a=>[0,a+a,a*a,a**a][a%4]

Try it online!

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

C, 63 or 62 bytes

#include<math.h>
f(x){return(int[]){0,x+x,x*x,pow(x,x)}[x&3];}

-1 byte if macros are allowed, assuming x is not an expression like 3+5 (since that'd mess up the precedence):

#include<math.h>
#define f(x)(int[]){0,x+x,x*x,pow(x,x)}[x&3]
\$\endgroup\$
  • \$\begingroup\$ @ceilingcat Right, forgot about that. \$\endgroup\$ – Tim Čas May 3 '17 at 12:15
  • \$\begingroup\$ does not compile on MSVS2015; Intellisense said cast to incomplete array type "int[]" is not allowed Compiler said error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax; ALSO! where is int f(int x)? code is actually at least 8 bytes longer; also it is very slow and inefficient, as it evaluates everytning - dont repeat it IRL) \$\endgroup\$ – user69099 May 9 '17 at 22:01
  • \$\begingroup\$ @xakepp35 What? 1) it has to compile in a C compiler. Most (read: just about all but MSVC) C compilers support this (int[]) syntax for this situation. 2) f(x) is perfectly legal C89. I didn't specify the standard. 3) This is about code size, not efficiency. And 4) If you're going to be patronizing, at least use a real compiler and/or check your facts. \$\endgroup\$ – Tim Čas May 10 '17 at 16:05
  • \$\begingroup\$ @Tim Čas Ah yes, rly sorry! I was trying to compile it as C++ code. That's my fault) It compiles and works great! \$\endgroup\$ – user69099 May 13 '17 at 0:44
2
\$\begingroup\$

Java 7, 75 bytes

long c(int n){int x=n%4;return x<1?0:x<2?n+n:x<3?n*n:(long)Math.pow(n,n);}

Even though it is valid according to the rules, long is 64-bits, so it fails for the exponentiation test cases of 19^19 and above. To fix that we can use a BigDecimal approach:

148 146 bytes

import java.math.*;BigDecimal c(int n){int x=n%4;BigDecimal m=new BigDecimal(n);return x<1?m.subtract(m):x<2?m.add(m):x<3?m.multiply(m):m.pow(n);}

Explanation (of BigDecimal approach):

import java.math.*;                // Import required for BigDecimal
BigDecimal c(int n){               // Method with integer parameter and BigDecimal return-type
  int x=n%4;                       //  Input modulo-4
  BigDecimal m=new BigDecimal(n);  //  Convert input integer to BigDecimal
  return x<1?                      //  If the input mod-4 is 0:
    m.subtract(m)                  //   Return input - input (shorter than BigDecimal.ZERO)
   :x<2?                           //  Else if the input mod-4 is 1:
    m.add(m)                       //   Return input + input
   :x<3?                           //  Else if the input mod-4 is 2:
    m.multiply(m)                  //   Return input * input
   :                               //  Else:
    m.pow(n);                      //   Return input ^ input
}                                  // End of method

Test code:

Try it here.

import java.math.*;
class M{
  static BigDecimal c(int n){int x=n%4;BigDecimal m=new BigDecimal(n);return x<1?m.subtract(m):x<2?m.add(m):x<3?m.multiply(m):m.pow(n);}

  public static void main(String[] a){
    for (int i = 1; i <= 25; i++) {
      System.out.print(c(i) + "; ");
    }
  }
}

Output:

2; 4; 27; 0; 10; 36; 823543; 0; 18; 100; 285311670611; 0; 26; 196; 437893890380859375; 0; 34; 324; 1978419655660313589123979; 0; 42; 484; 20880467999847912034355032910567; 0; 50; 
\$\endgroup\$
  • \$\begingroup\$ You don't need to fix the program this way :P The old answer would work if numbers had infinite size; the first program would have been valid under my specs. :P \$\endgroup\$ – HyperNeutrino May 1 '17 at 14:44
  • \$\begingroup\$ @HyperNeutrino Then I specify that in the answer.. Ah well, Java won't win any code-golf challenges anyway. ;) \$\endgroup\$ – Kevin Cruijssen May 1 '17 at 14:46
  • 1
    \$\begingroup\$ Yes, I would specify. And yes, it's Java, it's not going to win. :D \$\endgroup\$ – HyperNeutrino May 1 '17 at 14:47
  • 2
    \$\begingroup\$ "And yes, it's Java, it's not going to win. :D" I'm used to it. :P Even my shortest Java answer ever of 8 bytes is way to long compared to the golfing answers. xD Although it was the first time I had beaten a Python answer with my Java answer, which has to count for something I guess. ;) \$\endgroup\$ – Kevin Cruijssen May 1 '17 at 14:51
2
\$\begingroup\$

x86 Assembler, Intel syntax, 192 bytes

.data
f dw @q,@w,@e,@r
.code
mov ecx, eax
and ecx, 3
mov edx,dword ptr f[ecx*4]
call [edx]
ret
q:
xor eax,eax
ret
w:
add eax,eax
ret
e:
mul eax,eax
ret
r:
mov ecx,eax
t:
mul eax,eax
loop t
ret

Example pretends for fastest working speed. Is is a program or program part, which uses fastcall convention. It assumes input variable x in register eax, and returns result also in eax. Basic idea is stay away from using conditional jumps, as in some examples here. Also, it is not to evaluate everything (as in C example with arrays) but to use array of pointers to functons and make faster unconditional jumps (jmp/call) as an optimized "C language switch()-case.." analog. This technique could be also useful in kinds of finita automata - like processor emulators, executors and so on.

Upd: for x64 use "r" in register names, instead of "e" (e.g. rax instead of eax, rcx instead of ecx). Size will not be changed, and it will use 64-bit unsigned words.

\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! The objective of this challenge is to make your code as short as possible. In this case, your code could easily be shortened a bunch by combining all those function declarations. You can also remove some whitespace. \$\endgroup\$ – HyperNeutrino May 9 '17 at 22:46
  • \$\begingroup\$ @HyperNeutrino asm itself is kinda "long" language :) so i dont have an idea on how to make this shorter. any example-advices? \$\endgroup\$ – user69099 May 12 '17 at 23:05
  • \$\begingroup\$ Eh, sorry, I must have copied my comment on your C answer into this post. I don't know how to program in ASM but could you potentially remove some whitespace? \$\endgroup\$ – HyperNeutrino May 12 '17 at 23:14
  • \$\begingroup\$ @HyperNeutrino, sorry.. but seems no) it has to be longest code among others, i can just trunc windows crlf to linux format so 209->192 bytes, changes are not visible) \$\endgroup\$ – user69099 May 13 '17 at 1:00
  • \$\begingroup\$ Aw. That's too bad. But nice submission regardless! :) \$\endgroup\$ – HyperNeutrino May 13 '17 at 1:18
2
\$\begingroup\$

C#, 39 bytes

x=>new[]{0,2,x,Math.Pow(x,x-1)}[x&3]*x;

Explanation

Observe that:

(x-x, x+x, x*x, x^x) == (0, 2, x, x^(x-1)) * x

The solution creates an array, indexes into it and then multiplies the result by x:

x => new[] { 0, 2, x, Math.Pow(x,x-1) }[x&3] * x;

Alternative versions:

x=>new[]{0,x+x,x*x,Math.Pow(x,x)}[x%4];

(39B, all multiplication done in the array, x%4 replaces x&3)

x=>x%4<2?x%2*2*x:Math.Pow(x,x%4<3?2:x);

(39B, same as @MetaColon's answer but x%2*2*x replacing x*x%4<1?0:2)

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

Actually, 12 bytes

;;3&"-+*ⁿ"Eƒ

Try it online!

Explanation:

;;3&"-+*ⁿ"Eƒ
;;            two copies of input (so 3 total)
  3&          bitwise AND with 3
    "-+*ⁿ"E   index into this string
           ƒ  call the respective function
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 10 bytes

Ð"-+*m"è.V

Uses the 05AB1E encoding. Try it online!

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

J, 14 bytes

4&|{0,+:,*:,^~

Try it online!

\$\endgroup\$
  • \$\begingroup\$ (4&|{-,+,*,^)~ works as well but it's the same byte count due to parens, although it's slightly more obvious what it does. \$\endgroup\$ – Cyoce May 1 '17 at 17:47
1
\$\begingroup\$

Oasis, 25 bytes

mn4%3Q*nkn4%2Q*nxn4%1Q*++

Try it online!

How it works

Notice that x&3 is equivalent to x%4, where % is modulo.

mn4%3Q*nkn4%2Q*nxn4%1Q*++  input is n
mn4%3Q*                    (n**n)*((n%4)==3)
       nkn4%2Q*            (n**2)*((n%4)==2)
               nxn4%1Q*    (n*2)*((n%4)==1)
                       +   add the above two
                        +  add the above two

Oasis is a stack-based language where every character is a command.

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

Cubix, 29 bytes

.;.O+@.UOI:4%!^s;((?u.^P;<^*;

Try it online!

Explanation will be added soon...

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

C#, 42 Bytes

x=>x%4<2?x*x%4<1?0:2:Math.Pow(x,x%4<3?2:x)

Actually it's normal C#, but as you can't run it as a whole program and you have to type it into the interactive, I guess you may call it C# interactive.

Explanation:

x => (x % 4) < 2     //If the bits are smaller than 2 (1 or 0)
? x *           //multiply x with
    (x % 4) < 1 //if the bits are 0
    ? 0         //0 (results in 0)
    : 2         //or else with 2 (results in 2*x or x+x)
: Math.Pow(x,   //otherwise power x by
    (x % 4) < 3 //if the bits are 2
    ? 2         //2 (results in x^2 or x*x)
    : x);       //or else x (results in x^x)

I can't tell wether it's the shortest variant, any suggestions are appreciated.

\$\endgroup\$
  • \$\begingroup\$ I don't think that's valid. You generally should submit a program or function. Snippets are not allowed by default. \$\endgroup\$ – Cyoce May 1 '17 at 18:00
  • \$\begingroup\$ @Cyoce It is a program. You just have to run it through the interactive, which will interpret the program. \$\endgroup\$ – MetaColon May 1 '17 at 18:37
  • \$\begingroup\$ When I run this in interactive, I get an error because x is not defined. That makes this a snippet, not a full program. \$\endgroup\$ – Cyoce May 1 '17 at 18:58
  • \$\begingroup\$ @Cyoce In the challenge it said, there'd be a variable x defined. \$\endgroup\$ – MetaColon May 1 '17 at 19:00
  • \$\begingroup\$ That's not what that means. "Given a positive integer x" means that you are being given x through a standard input method (i.e., function or program). \$\endgroup\$ – Cyoce May 1 '17 at 19:02
1
\$\begingroup\$

PHP, 36 bytes

<?=[0,2,$x=$argn,$x**~-$x][$x&3]*$x;
\$\endgroup\$
1
\$\begingroup\$

dc, 27

I've never had the occasion to use arrays in dc before:

[+]1:r[*]2:r[^]3:r?dd4%;rxp

Try it online.

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

Groovy, 26 bytes

{x->[0,x+x,x*x,x**x][x%4]}

Try it online!

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

C, 115 bytes

#include<math.h>
#define D(K,L)K(x){return L;}
D(q,0)D(w,x+x)D(e,x*x)D(r,pow(x,x))(*g[])()={q,w,e,r};D(f,g[x%4](x))

Example is a function int f(int x)

It pretends for fastest working speed as it keeps CPU away from using conditional jumps. And this is only correct speed-optimisation way for this task. Also, it tries not to evaluate everything, as in array C example return(int[]){0,x+x,x*x,pow(x,x)}[x%4]; But but to wisely use array of pointers to functons, in order to make much faster unconditional jumps (jmp/call) with much faster address arithmetics, as an optimized version of "switch()-case..". This technique could be also useful in several kinds of finita automata - like processor emulators, executors, command stream parsers, and so on - where speed matters and code like switch(x%4) case(0):... case(1):... is unsuitable because it produces multiple cmp/jnz instructions; and these are costly operations for CPU

Simpliest and shortest test program (in default conditions) for the case will be as follows:

D(main,f(x))

It will add just 12 bytes of payload and will total our size to 127 bytes;

But you should better tell the linker to use f function as an entry point, instead of main. That is the way, if we aim to get fastest possible working binary for this task from shortest code ;-) This happens because C library adds extra init/shutdown code before calling your main() function.

Code compiles on MSVS Community 2015 without any tricks and issues and produces correct results. I haven't tested it with gcc, but i'm sure it will work fine as well.

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to PPCG! The objective of this challenge is to make your code as short as possible. In this case, your code could easily be shortened a bunch by combining all those function declarations. You can also remove some whitespace. \$\endgroup\$ – HyperNeutrino May 9 '17 at 22:46
  • \$\begingroup\$ I like the idea of using pointers to functions \$\endgroup\$ – RosLuP May 11 '17 at 18:11
  • \$\begingroup\$ @RosLuP ye, but its almost twice longer than your 60 bytes version. but it works much faster, it is worth its size. \$\endgroup\$ – user69099 May 13 '17 at 1:09
  • \$\begingroup\$ @Hyper Neutrino Okay. I've compressed it more. Seems, this is final version! There are no bugs, all tests passed 8-) \$\endgroup\$ – user69099 May 13 '17 at 1:27
  • \$\begingroup\$ @xakepp35 did you measure your is faster than my? \$\endgroup\$ – RosLuP May 13 '17 at 10:02
1
\$\begingroup\$

R, 47 42 bytes

x=scan();c(`-`,`+`,`*`,`^`)[[x%%4+1]](x,x)

Applies the function -, +, *, or ^ based on the modulus of x to x and x.

- is the only (somewhat) smart thing, since x-x is always 0.

R, 33 bytes

pryr::f(c(0,2*x,x^2,x^x)[x%%4+1])

Same method as other people use. Though it is shorter, I don't like it nearly as much.

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

Pyth, 12 bytes

.vjd,+@"-+*^

Try it online!

How it works

Firstly, notice that x&3 is equivalent to x%4, where % is modulo. Then, since Pyth uses modular indexing (a[n] == a[n+len(a)]), so we don't even need to deal with that.

Then:

  • If x%4==0, return x-x (for consistency);
  • If x%4==1, return x+x;
  • If x%4==2, return x*x;
  • If x%4==3, return x^x.

.vjd,+@"-+*^  example input: 10
      @"-+*^  "-+*^"[10], which is "*"
     +        "*10"
    ,         ["*10","10"]
  jd          "*10 10"
.v            evaluate as Pyth expression
              (Pyth uses Polish notation)

More about Polish notation: Wikipedia (too bad if you are in Turkey).

\$\endgroup\$
  • \$\begingroup\$ Huh? This just seems too much to me. See my answer for details. \$\endgroup\$ – Erik the Outgolfer May 1 '17 at 16:31
0
\$\begingroup\$

Japt, 13 bytes

Ov"^+*p"gU +U

Try it online!

This uses the same method as the other eval answers, except the program -U just negates U, so we use ^ (bitwise XOR) instead.

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

Vim, 50 bytes

y$o^R"A-+*^^V^[0^R"lx0"_Dp^[0D@"kJ0"ad$:r!echo ^R"^R0|bc^<Enter>

Here, ^V represents a Ctrl+V, ^R represents Ctrl-R and ^[ represents the esc key

Works by first building up the expression and then letting bc evaluate it. Expects the input on the first line in an otherwise empty buffer.

Explanation:

y$o^R"                                                          Copies the input into register " and pastes it on the second line
      A-+*^^V^[0^R"lx0"_Dp                                      Enters that text after the input on the second line
                          ^[0D@"                                Executes the second line as a Vim command.
                                                                For example, if the input is 12, the second line would be 12A-+*^^[012lx0"_Dp, which means:
                                                                  12A-+*^^[           Insert the text -+*^ 12 times
                                                                           012lx0"_Dp Go 12 chars to the right and remove everything except for that.
                                                                If effect, this basically just selects the appropriate operation.
                                kJ0"ad$                         Put the operator after the number, cut it into register a
                                       :r!                      Execute the following shell command and put the result into the buffer:
                                          echo ^R"^R0|bc<Enter> The shell command "echo [contents of register a][contents of registers 0]|bc. As said above, register a contains the input and the operator, and register 0 contains the input. The <enter> then executes this command.
\$\endgroup\$
  • \$\begingroup\$ When I type ^V it just pastes what I have in my clipboard, instead of the number... \$\endgroup\$ – Leaky Nun May 1 '17 at 15:06
  • 1
    \$\begingroup\$ Try it online! Also, You can do D instead of d$ \$\endgroup\$ – DJMcMayhem May 1 '17 at 17:46
0
\$\begingroup\$

Pyth, 9 bytes

@[0yQ*QQ^

Test suite

Nothing fancy going on here, just calculate the four values, and select one with modular indexing.

@[0yQ*QQ^
@[0yQ*QQ^QQ)Q    Implicit variable introduction
@           Q    Modularly index into the following list
 [0        )     0
   yQ            Q*2
     *QQ         Q*Q
        ^QQ      Q^Q
\$\endgroup\$
0
\$\begingroup\$

Batch, 135 bytes

@set/an=%1*2^&6
@goto %n%
:6
@set n=1
@for /l %%i in (1,1,%1)do @set/an*=%1
@goto 0
:4
@set n=%1
:2
@set/an*=%1
:0
@echo %n%

I was hoping to create the exponentiation by building up and evaluating a string of the form [0+...+0, 2+...+2, x+...+x, x*...*x] depending on the last two bits of x but unfortunately the code to select the operation took too long to express because I couldn't use * as a for parameter, but I was at least able to use some fall-though trickery to golf away some bytes.

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

Retina, 87 bytes

.+
$*1;$&$*
;((1111)*)(1?)$
;$3$3
1(?=1.*;((1111)*111)$)
$1;
+`\G1(?=.*;(1*))|;1*$
$1
1

Try it online! (Link includes test suite.)

Explanation: The first two lines convert the input into unary and duplicate it (so we now have x;x). The next two lines look for an x&3 of either 0 or 1 and change x;x into x;0 or x;2 appropriately. The next two lines look for x&3==3 and change x;x into x;x;x;...;x;1;x (x xs). This means that we have either x;0, x;2, x;x, or x;...;x and it remains to multiply everything together and convert back to decimal. (The multiplication code is based on that in the Retina wiki but amended to handle multiplication by zero.)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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