32
\$\begingroup\$

Recently (okay, December 2023, I'm a little late) there's been a meme going around about a program checking if a 32-bit unsigned integer is even or odd using four billion if statements:

if num == 0:
    print("even")
if num == 1:
    print("odd")
if num == 2:
    print("even")
...
if num == 4294967294:
    print("even")
if num == 4294967295:
    print("odd")

Today, you'll be writing a program/function that outputs something similar to this. Your code should take no input and output source code, in the same language, for a function or program that takes an unsigned 32-bit integer (0 ≤ n ≤ 4294967295) and outputs/returns either "even" if the input is even and "odd" otherwise. For clarity, I'll use "program" for the rest of this post, but everything here also applies to function submissions.

Specifically, the resulting program should be divisible into a "header", 4294967296 "segments", and a "footer", such that concatenating the header, the i+1th segment, and the footer results in a program that:

  • When given i, prints either "even" or "odd" depending on i's parity
  • When given any unsigned 32-bit integer that's not i, does something else - this can include crashing, printing nothing, or printing anything else, as long as it doesn't print only "odd" or "even".

For example, with the following C code:

#include <stdlib.h>
int main(int argc, char* argv[]) {
    unsigned int number = atoi(argv[1]);
    if (number == 0)
        printf("even\n");
    if (number == 1)
        printf("odd\n");
    if (number == 2)
        printf("even\n");
    // etc etc
    if (number == 4294967294)
        printf("even\n");
    if (number == 4294967295)
        printf("odd\n");
}

Here, the #include <stdlib.h>; int main(int argc, char* argv[]) { unsigned int number = atoi(argv[1]); is the header, the } is the footer, and the if (number == 2) printf("even\n"); are the segments. Concatenating e.g. the 136th segment with the header and footer results in the following:

#include <stdlib.h>
int main(int argc, char* argv[]) {
    unsigned int number = atoi(argv[1]);
    if (number == 135)
        printf("odd\n");
}

which indeed prints "odd" if given 135 and outputs nothing otherwise.

Here's an example of a generating program in Python.

As per standard I/O, "even" / "odd" may be output with any (including none) amount of leading/trailing whitespace. It's fine if, due to program size/memory/language limitations (e.g. Java source files being at most 1GB), the resulting program doesn't compile, as long as it works in theory.

This is , the shortest generating program wins!

\$\endgroup\$
19
  • 1
    \$\begingroup\$ Some language (JDK for example) have limitation about size of source code, so it typically failed to compile the code. If this is the case, will this invalid the answer? Since it could be hard for anyone to make a real test on if output source actually works... \$\endgroup\$
    – tsh
    Commented Sep 24 at 8:02
  • \$\begingroup\$ Must it also work for any combination of segments? In particular, with all segments, must it be a complete working program? \$\endgroup\$
    – Tbw
    Commented Sep 24 at 8:04
  • 1
    \$\begingroup\$ @Tbw The only requirements are that a) it works with all segments b) it works with any individual segment. \$\endgroup\$
    – emanresu A
    Commented Sep 24 at 8:18
  • 1
    \$\begingroup\$ Are we allowed to do actual even/odd checks if it's shorter? In pseudo-code: instead of if (input == 0) print("even"); if (input == 1) print("odd"); ... it would be if (input == 0) print(["even","odd"][input%2]); if (input == 1) print(["even","odd"][input%2]); ...? We'd still have the segments, although it's not really similar to the generic implementation. \$\endgroup\$ Commented Sep 24 at 12:21
  • 1
    \$\begingroup\$ Sort of a non-answer, but godbolt.org/z/PdhWM6d6M is a C++ template function that uses if constexpr(limit) f<limit-1>(x) so it's a compact-ish (not fully golfed) C++ program that itself does all the compares. Compiling it produces blocks of asm that are somewhat close to meeting the question's requirements, but GCC decides to put the print part in the middle instead of footer. GCC's default template recursion depth is only 900 so I'm not optimistic about raising that and actually compiling it with a high limit. A tree instead of linear recursion would cut depth to log2 n. \$\endgroup\$ Commented Sep 27 at 0:47

26 Answers 26

16
\$\begingroup\$

Python 3, 70 bytes

print("def f(n):f",*range(2**33),sep="==n==print('eovdedn'[n&1::2]);")

Try it online (with 2**3 in place of 2**33)

If it's OK for the function to error out after printing, 1 byte can be saved by writing <print(...) in place of ==print(...).

\$\endgroup\$
2
  • 2
    \$\begingroup\$ So, why 2**32+2, why not 2**33 \$\endgroup\$
    – tsh
    Commented Sep 24 at 8:49
  • 3
    \$\begingroup\$ @tsh I guess nothing does prevent claiming that all the extras are part of the footer, good point \$\endgroup\$
    – xnor
    Commented Sep 24 at 8:50
13
\$\begingroup\$

Bash, 59 (Theoretical)

  • 3 bytes saved thanks to @NahuelFouilleul
printf "${f=((\$1-%d))||echo} even
$f odd
" {0..4294967295}

If bash could do the brace expansion {0..4294967295} and pass the result as command-line args to printf then this would work. The result of the expansion is going to be a memory allocation at least in the 45GB range, so bash understandably barfs at this.

Try it online!

The output looks like this:

(($1-0))||echo even
(($1-1))||echo odd
(($1-2))||echo even
(($1-3))||echo odd
.
.
.
(($1-4294967294))||echo even
(($1-4294967295))||echo odd

As a proof-of-concept, this can be scaled down to something that works fine within the constraints of bash and TIO:

printf "${f=((\$1-%d))||echo} even
$f odd
" {0..4095}

Try it online!


Bash, 76 bytes (Actual)

for((i=2**32;i--;)){ printf "${f=((\$1-%d))||echo} odd
$f even
" $i $[--i];}

This one will take several hours (days?) to run, so again TIO won't be happy with this, but it will complete eventually given enough time and disk space for the resulting script.

Try it online!

Again, a scaled-down proof-of-concept for TIO. Same as the above except 2**32 is replaced with 2**12:

for((i=2**12;i--;)){ printf "${f=((\$1-%d))||echo} odd
$f even
" $i $[--i];}

Try it online!

\$\endgroup\$
3
  • 3
    \$\begingroup\$ 59 bytes using parameter unset assigned expansion Try it online! \$\endgroup\$ Commented Sep 25 at 13:42
  • \$\begingroup\$ Looks like a bash bug: I tried this on a computer with ~120GB free RAM and bash still barfed! the required ram was available! \$\endgroup\$
    – hanshenrik
    Commented Sep 26 at 8:38
  • \$\begingroup\$ @hanshenrik : using dichotomy ( N ko ? try N/2. N/2 ok ? try 3N/4, etc) you should pinpoint the exact point where it barfs in just a few tries (it divides the remaining looking range by 1/2, and thus finishes in logN with the precise choke value) \$\endgroup\$ Commented Sep 26 at 11:29
7
\$\begingroup\$

C (gcc), 104 93 bytes

f(i){puts("g(x){");for(i=0;printf("x-%u?:puts(\"%s\");",i,i--%2?"even":"odd"),i;);puts("}");}

Outputs "segments" in reverse order.

-11 thanks to Digital Trauma and SquareFinder

Try it online!

\$\endgroup\$
11
  • 2
    \$\begingroup\$ I think this works for 93 bytes. 1) use ?: instead of if(){} boilerplate. 2) Explicitly declaring unsigned seems unnecessary. 3) Fixed bug where if(x==0) was not emitted. \$\endgroup\$ Commented Sep 24 at 19:48
  • 1
    \$\begingroup\$ @DigitalTrauma unless i'm mistaken, the order of evaluation in a function is not specified in C so i-- may not necessarily be evaluated after i (I think this might also be undefined behaviour) \$\endgroup\$ Commented Sep 24 at 23:40
  • 2
    \$\begingroup\$ @DigitalTrauma in that case, you can neglect setting i=0 and do this instead for 92 bytes \$\endgroup\$ Commented Sep 25 at 0:37
  • 2
    \$\begingroup\$ I think you need to specify unsigned x in the generated code, right now any input above the signed integer maximum does not give any output (e.g. 4294967295) \$\endgroup\$ Commented Sep 25 at 9:51
  • 2
    \$\begingroup\$ Alternative 92-byte solution assigns i using the otherwise wasted puts(): f(i){for(i=!puts("g(x){");printf(…. \$\endgroup\$ Commented Sep 26 at 12:09
6
+100
\$\begingroup\$

JavaScript (Node.js), 57 bytes

for(a='x=>',i=0;a+=i+'==x?x%2?"odd":"even":',~i++;)_=>a+_

Try it online!

tsh suggests bitwise operator.

Python 3.8 (pre-release), 67 bytes

print("def f(n):n in",[*range(2**32)],"==print('eovdedn'[n&1::2])")

Try it online!

pog

\$\endgroup\$
2
  • \$\begingroup\$ for(i=0,a='x=>';a+=`x==${i++}?x%2?"odd":"even":`,i|0;); \$\endgroup\$
    – tsh
    Commented Sep 24 at 8:14
  • \$\begingroup\$ Nice Python solution! I'll post a bounty \$\endgroup\$
    – xnor
    Commented Sep 26 at 1:56
5
\$\begingroup\$

Wolfram Language (Mathematica), 43 bytes

<|#-1->"odd"?"even"[[(-1)^#]]&~Array~5*^9|>

Try it online! with a smaller upper bound of 5*^3

-4 bytes returning a symbol: remove the "s.

Evaluates to a function (Association) that returns a string "even" or "odd", or Missing["KeyAbsent", i] if the corresponding segment is not included. Its 106388888892-character string representation can be split into:

  • A header <|,
  • 4294967296 segments of the form i -> "odd"|"even", ,
  • and a 15158203136-character footer that begins 4294967296 -> "even", and ends 4999999999 -> "odd"|>.
\$\endgroup\$
5
\$\begingroup\$

Fortran (GFortran), 180 164 bytes

integer*8n;character*8t;print*,'integer*8i';print*,'read*,i'
do n=0,2**32-1;t='"even"';if(mod(n,2)>0)t='"odd"'
print*,'if(i==',n,')print*,',t;enddo;print*,'end'
end

Try it online! 180B

Outputs a valid Fortran program. Example

\$\endgroup\$
1
  • 1
    \$\begingroup\$ You can save 13 bytes by rewriting the third line as t='"even"';if(mod(n,2)>0)t='"odd"'. \$\endgroup\$
    – Dingus
    Commented Sep 24 at 12:20
5
\$\begingroup\$

Bash, 95 bytes

${c=echo }case \$1 in
for ((i=0;i<2**32;i++));{
$c"$i)$c`((i%2))&&$c\odd||$c\even`;;"
}
$c\esac

Attempt This Online!

-20 bytes by DigitalTrauma
-48 bytes by myself, with a simple for loop

header:

case $1 in

segments:

i)echo even/odd;;

footer:

esac

Explanation:

${c=echo } both assigns the variable $c to echo (note the trailing space), and expands said variable. after expansion, the whole script becomes

echo 'case $1 in'
for ((i=0;i<2**32;i++));{
echo "$i)echo `((i%2 == 1))&&echo odd||echo even`;;"
}
echo 'esac'

from here, the rest should be easy enough to follow, once you know that in bash, code in backticks is executed, then the backticks and their contained code are replaced by the standard output of that execution

\$\endgroup\$
5
  • \$\begingroup\$ Interestingly my bash (5.0.17(1) - Ubuntu 20.04.6) doesn't expand {1..4294967295..2} - it just returns the same {1..4294967295..2} as the expansion result. It does seem to be able to do up to {1..4294967289..2} - at least it sits for a long time thinking about it \$\endgroup\$ Commented Sep 24 at 17:16
  • \$\begingroup\$ -39 bytes. Note more than one case per line should be OK \$\endgroup\$ Commented Sep 24 at 17:53
  • \$\begingroup\$ @DigitalTrauma Mine (5.1.16(1)-release) returns a memory error almost instantly for large numbers up to 4294967290, then returns the original string unmodified for numbers above that as yours does. I tried it with 2147483648 out of curiosity, and it sat there for a few seconds before erroring so hard the terminal window disappeared. \$\endgroup\$
    – Bbrk24
    Commented Sep 25 at 0:17
  • \$\begingroup\$ The largest power of two for which it doesn't error for me is 33554432. \$\endgroup\$
    – Bbrk24
    Commented Sep 25 at 0:22
  • \$\begingroup\$ @DigitalTrauma: i don't think more than one case per line meets the spec, because you then have difficulty defining what the correct ith segment is in a way that's not too contrived. nice catch on the rest though. \$\endgroup\$ Commented Sep 25 at 7:40
4
\$\begingroup\$

Japt -P, 24 bytes

2pH Ç+"¶U?Ug`eov¸dn`ó:(P

Test it (limited to 65535 so it will actually run) or test the generated programme (limited to 100)

2pH Ç+"¶U?Ug`eov¸dn`ó:(P
2p                           :2 raised to the power of
  H                          :  32
    Ç                        :Map the range [0,2pH)
     +"¶U?Ug`eov¸dn`ó:(P     :  Append literal string
                             :Implicitly join and output
0¶U?Ug`eov¸dn`ó:(P1¶U...     :Implicit input of integer U
0¶U?                         :If 0 is equal to U
    Ug                       :  Index U into (0-based, with wrapping)
      `eov¸dn`               :    Compressed string "eovdedn"
              ó              :    Uninterleave
               :             :Else
                (            :  Group the following statements
                 P           :    Empty string
                  1¶U...     :    Start all over again, checking if 1 is equal to U
\$\endgroup\$
6
  • \$\begingroup\$ Out of interest, how long would a generator for a direct port of the meme be? (I'll accept a port that uses if/else rather than separate if statements.) \$\endgroup\$
    – Neil
    Commented Sep 25 at 5:57
  • \$\begingroup\$ Japt doesn't have if(/else) statements, @Neil. The closest I could get to the spec would be to use logical AND with explicit output, which would be the same byte count. \$\endgroup\$
    – Shaggy
    Commented Sep 25 at 10:57
  • \$\begingroup\$ So why does your description say If 0 is equal to U? (It was really the specific odd/even output per if statement that I was looking for anyway.) \$\endgroup\$
    – Neil
    Commented Sep 25 at 11:15
  • \$\begingroup\$ That was just me combining the explanation of the (stritcty equal to comparison operator) and the ternary operator into one line. Alternating between "even" and "odd" for each statement would cost me ~4 bytes. \$\endgroup\$
    – Shaggy
    Commented Sep 25 at 11:22
  • 1
    \$\begingroup\$ Fair enough, the ternary operator also counts as if/else for me, thanks. \$\endgroup\$
    – Neil
    Commented Sep 25 at 12:56
4
\$\begingroup\$

Perl 5, 58 bytes

say'$_=<>';say";\$_-$_||say ",(even,odd)[$_%2]for 0..2**32

Try it online!

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

Charcoal, 27 26 24 bytes

FXχχ«´¿´⁼Iι´θ§⪪evenodd⁴ι

Attempt This Online! Link is to verbose version of code and only goes up to 100 (the default interpreter can't actually handle deeply nested if statements anyway). The resulting program has no header but technically has a footer for the purposes of the question. Explanation:

FXχχ«

Loop more than enough times. (The remaining times count as part of the footer.)

´¿´⁼

Output the characters for If and Equals. (´ is Charcoal's escape character.)

Iι

Output the current value.

´θ

Output the character that represents the (first) input. The program assumes default input where this will be a string.

§⪪evenodd⁴ι

Output odd or even depending on the parity of the current value.

The resulting program is a giant nested if statement (Charcoal will nest if unless it is the last statement in a block, which can't be readily arranged here):

¿⁼0θeven¿⁼1θodd¿⁼2θeven¿⁼3θodd¿⁼4θeven¿⁼5θodd¿⁼6θeven¿⁼7θodd...

Attempt This Online! Link only goes up to 100 and includes AST for convenience. Explanation: See generator for what the individual characters mean.

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

MathGolf, 22 bytes

♥ór{"]y=╛{♣A+╦╖8Çα§q}"

(Will output nothing for undefined inputs - e.g. any negative integers; positive integers above 4294967295; or non-integer inputs.)

Try it online with max 31 instead of 4294967295.
Try the outputted program.

Explanation:

♥                      # Push 32
 ó                     # Pop and push 2**32: 4294967296
  r                    # Pop and push a list in the range [0,4294967296)
   {                   # For-each over this list:
                       #  (implicitly push the current value)
    "]y=╛{♣A+╦╖8Çα§q}" #  Push this string
                       # (after the loop, everything on the stack is joined
                       # together and output implicitly as result)

Explanation of the resulting program:

0]y                    # Push 0†:
0                      #  Push digit 0
 ]                     #  Wrap the entire stack into a list
  y                    #  Join this list together to an integer
   =╛{          }      # If the (implicit) input-integer equals this:
      ♣A+              #  Push 139 (128+11)
         ╦             #  Pop and push the 139th dictionary word: "even"
          ╖8Ç          #  Push compressed integer "odd"
             α         #  Pair the two together ["even","odd"]
              §        #  0-based modular index the (implicit) input into it
               q       #  Pop and print it††

† In MathGolf, every digit is pushed to the stack separately. So if you write e.g. 513, it would push three separated digits (5;1;3) instead of the number 513 itself. Since the size of the numbers varies in the range [0,4294967295], I'd added the generic ]y (wrap + join to integer) here.


There seem to be some bugs in MathGolf, since I feel like both the q and trailing " shouldn't be necessary here..

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

Sed, 184 bytes

I count 174 for the program and 10 bytes of input (since sed can't run without input)

s,.*,s/&/,
:y
s,/,_/,2
:o
s/0_/_9/
s/1_/0/
s/2_/1/
s/3_/2/
s/4_/3/
s/5_/4/
s/6_/5/
s/7_/6/
s/8_/7/
s/9_/8/
to
s/[oe].*//
s,[13579]/,&odd/,
/d/!s,$,even/,
\,/0/,q
s,/0,/,
p
by

Feed this with number of numbers to recognise (i.e. 4294967296) as input, and it produces:

s/4294967295/odd/
s/4294967294/even/
s/4294967293/odd/
s/4294967292/even/
s/4294967291/odd/
s/4294967290/even/
s/4294967289/odd/
s/4294967288/even/
s/4294967287/odd/
s/4294967286/even/
s/4294967285/odd/
s/4294967284/even/
s/4294967283/odd/
s/4294967282/even/
s/4294967281/odd/
s/4294967280/even/
⋮
s/15/odd/
s/14/even/
s/13/odd/
s/12/even/
s/11/odd/
s/10/even/
s/9/odd/
s/8/even/
s/7/odd/
s/6/even/
s/5/odd/
s/4/even/
s/3/odd/
s/2/even/
s/1/odd/
s/0/even/

We have to produce the tests in descending order, otherwise it would match substrings before the entire number.

Explanation

#!/bin/sed -f

# Initialise - turn the number into a sed command
s,.*,s/&/,

# Loop from n to 0
:y

# subtract one
s,/,_/,2
:o
s/0_/_9/
s/1_/0/
s/2_/1/
s/3_/2/
s/4_/3/
s/5_/4/
s/6_/5/
s/7_/6/
s/8_/7/
s/9_/8/
to

# Odd or even
s/[oe].*//
s,[13579]/,&odd/,
/d/!s,$,even/,

# Did we reach zero?
\,/0/,q
# Remove any leading zero
s,/0,/,
# print and repeat
p
by

Try it online.

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

Brachylog, 38 bytes (very inefficient)

2^₃₂-₁⟦;["∧\"even\"|","∧\"odd\"|"]zwᵐ²

Try it online!

Try it with 2^4 instead to see it working

Explanation

2^₃₂-₁⟦                                  Take the list [0, 1, …, 2^32 - 1]
     ;["∧\"even\"|","∧\"odd\"|"]z     Circular zip with ["∧\"even\"|","∧\"odd\"|"]
                                  wᵐ²  Write everything

The resulting program is very simple:

0∧"even"           Input = 0 and Output = "even"
        |           Or
         1∧"odd"   Input = 1 and Output = "odd"
                |   Or…

Brachylog, 45 bytes (way more efficient)

2^₁₆>ℕ×₂gj+₁ᵗ;["∧\"even\"|","∧\"odd\"|"]zwᵐ²⊥

Try it online!

Explanation

2^₁₆>ℕ                                           Take a number I between 0 and 2^16
       ×₂                                         J = I × 2
         gj+₁ᵗ                                    [J, J + 1]
              ;["∧\"even\"|","∧\"odd\"|"]z       Zip J with "∧\"even\"|" and J+1 with "∧\"odd\"|"
                                           wᵐ²    Write everything 
                                              ⊥   False: this will force to retry write with different values of J
\$\endgroup\$
3
\$\begingroup\$

05AB1E, 28 25 18 bytes

žJÝ"Qi„ƒÎ¿»#sèë"«J

(Will output a space for undefined input 4294967296; and the input itself for any negative integers; positive integers above 4294967296; or non-integer inputs.)

Try it online with max 25 instead of 4294967295.
Try the outputted program.

Explanation:

žJ                # Push constant 4294967296
  Ý               # Pop and push a list in the range [0,4294967296]
"Qi„ƒÎ¿»#sèë"«    # Append string "Qi„ƒÎ¿»#sèë" to each
              J   # Join this entire string together
                  # (after which this string is output implicitly as result)

Explanation of the resulting program:

0Qi               # If the (implicit) input-integer is equals to 0:
   „ƒÎ¿»          #  Push dictionary string "even odd"
        #         #  Split it on spaces: ["even","odd"]
         sè       #  0-based modular index the input into it
  ë               # Else:
   1Qi            #  If the (implicit) input-integer is equals to 1:
      „ƒÎ¿»#sè    #   Do the same again
     ë            #  Else:
      2Qi         #   If the (implicit) input-integer is equals to 2:
         „ƒÎ¿»#sè #    Do the same again
        ë         #   Else:
         ...      #    etc.
                  # (then output the top of the stack implicitly as result)

See this 05AB1E tip of mine (section How to use the dictionary?) to understand why „ƒÎ¿» is "even odd".

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

Jelly,  18  16 bytes

Ø%ŻṾ⁾fị“£Ƙ®“⁴Ḍ»Ṿ

A full program that prints the code of a full program. (Or a monadic Link that yields the code of a full program as a list of characters.)

The output of a partial program when the input is not \$i\$ is empty.

Don't try it online! (Memory requirements.)

Here is a version that uses \$2^5 - 1\$ as the upper bound instead (replacing Ø% \$=2^{32}\$ with 32 \$=32\$).

Here is a test-suite for the partial code when \$i=11\$, again with a reduced upper bound of \$31\$.

The generated code consists of:

  • a header: empty string
  • segments: \$i\$ (in decimal) followed by a comma
    • e.g. the \$174\$th segment, for \$i=173\$, is 173,
  • a footer: 4294967296fị“odd“even”

How?

The generated code is run as a full program with an integer input \$n \in [0,2^{32}-1]\$:

0,1,2,3,...4294967295,4294967296fị“odd“even” - Main Link: integer, n, from [0..2³²-1]
0,1,2,3,...4294967295,4294967296             - list of integers -> [0..2³²]
                                f            - filter keep n -> [n]
                                  “odd“even” - list of lists of characters = ["odd", "even"]
                                 ị           - {[n]} index each into {["odd", "even"]}
                                                 (1-indexed and modular)
                                             - print
                                                 (singleton lists print their only element)

The partial code using only the \$(i+1)\$th segment is run as a full program with an integer input \$n \in [0,2^{32}-1]\$:

<i>,4294967296fị“odd“even” - Main Link: integer, n, from [0..2³²-1]
<i>,4294967296             - list of integers -> [i..2³²]
              f            - filter keep {n} -> [i] if n==i else []
               ị“odd“even” - as above, but an empty list prints nothing

The generating code is a full program that takes no input and works like this:

Ø%ŻṾ⁾fị“£Ƙ®“⁴Ḍ»Ṿ - Main Link: no arguments
Ø%               - 2³²
  Ż              - zero range -> [0..2³²]
   Ṿ             - unevaluate -> "0,1,2,...,4294967296"
                 - implicit print
    ⁾fị          - list of characters -> "fị"
                 - implicit print
       “£Ƙ®“⁴Ḍ»  - list of lists of characters -> ["odd", "even"]
               Ṿ - unevaluate {that} -> "“odd“even”"
                 - implicit print
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Out of interest, how long would a generator for a direct port of the meme be? (I'll accept a port that uses if/else rather than separate if statements.) \$\endgroup\$
    – Neil
    Commented Sep 25 at 5:58
  • \$\begingroup\$ @Neil it depends on your definition of "direct". As an example “⁴Ḍ“£Ƙ®»Ṿ€;€⁾ḷ$⁾⁼¡ṭⱮṁØ%J’ż@Ɗ (28 bytes, but may be improbable - replace Ø% with 32 to try it out :p) gives no header or footer with sections like “<parity>”ḷ$⁼¡<i> e.g. “even”ḷ$⁼¡14, but prints \$n\$ if it's not \$i\$ and does not work in exactly the same way (each non-initial if statement is actually testing the output of the previous if statement, which is either \$n\$ or a parity string we've found). \$\endgroup\$ Commented Sep 25 at 12:11
  • \$\begingroup\$ *improbable -> improvable. (Same for 26 with “⁴Ḍ“£Ƙ®»Ṿ€“ḷ$⁼¡”ṭⱮṁ32J’ż@Ɗ) \$\endgroup\$ Commented Sep 25 at 12:48
  • \$\begingroup\$ Thanks, as long as the code only prints odd or even for those sections that have been included then that seems to be reasonable. \$\endgroup\$
    – Neil
    Commented Sep 25 at 13:00
  • \$\begingroup\$ Are you sure this is valid? The crux of the challenge seems to be that the generated programme should make use of conditionals. \$\endgroup\$
    – Shaggy
    Commented Sep 26 at 23:43
3
\$\begingroup\$

C++ (gcc), 176 137 136 bytes

#import<cstdio>
f(){puts("#import<cstdio>\nf(unsigned x){");for(int i;printf("x-%u?:puts(\"%s\");",i,i++&1?"even":"odd"),i;);puts("}");}

Try it online!

The case when i = 0 comes last.

Uses -fwrapv flag for well-defined signed integer overflow wrapping (as opposed to the standard's undefined behaviour when overflowing).

Uses -fpermissive flag to suppress errors from defining f without a type

Thanks to Neil for suggesting changing printf to puts.

Borrows from the C (gcc) answer.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ I think you can change three of those printf to puts. \$\endgroup\$
    – Neil
    Commented Sep 24 at 16:31
  • \$\begingroup\$ (then reads the next answer, which has done exactly the same thing...) \$\endgroup\$
    – Neil
    Commented Sep 24 at 16:32
  • \$\begingroup\$ @Neil thanks, I knew I was forgetting something \$\endgroup\$ Commented Sep 24 at 23:31
  • 1
    \$\begingroup\$ I didn't realise that g++ allows f() with no return type. That's very permissive! \$\endgroup\$ Commented Sep 26 at 12:04
3
\$\begingroup\$

vim, 80 bytes

a"ncw
1 odd
2 even<ESC>oVkyPjj2<C-V><C-A>j2<C-V><C-A><ESC>0"aDdd2147483647@ao<C-V><ESC>"npi:v/^<C-V><ESC>A /d<C-V><ESC>0D@"
dw<ESC>

<ESC> is 0x1b, <C-V> is 0x16, <C-A> is 0x01.

Ungolfed:

; print the header and the first two segments
a
  "ncw
  1 odd
  2 even
<ESC>

; print a line that, if executed as a command, will copy the
; previous two lines, and increment each number by 2
o
  VkyPjj2<C-V><C-A>j2<C-V><C-A>
<ESC>

; pull that command into a register and execute it (2^32-2)/2 times.
0"aDdd2147483647@a

; print the footer. 
o
  <C-V><ESC>"npi:v/^<C-V><ESC>A /d<C-V><ESC>
  0D@"
  dw
<ESC>

Excerpt of generated program:

"ncw
1 odd
2 even
3 odd
4 even
5 odd
<ESC>"npi:v/^<ESC>A /d<ESC>0D@"
dw

The file will begin with a single line containing N. The header pulls that into register n, and then enters insert mode.

Each of the segments is then parsed while in insert mode, so when we hit the <ESC>, we end up with a file containing "1 odd\n2 even\n3 odd\n...".

The footer then retrieves register n and appends a line that, when executed, will scan through all segments and delete the ones that don't match n. It then pulls the command into a register and executes it, and then finally deletes the numeric part of the remaining line.

Try it online (with just the first 30 segments)

For some reason, TIO doesn't want to execute the macro at the end of the generated code, so you'll have to run that one in vim. Save the output from the first TIO as a.vim, then open a file with a single number in it, and run so! a.vim.

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

Nim,  111  110 bytes

echo"proc(n:int)=echo(case n"
for i in 0..<2 shl 32:echo "of ",i,":",repr ["even","odd"][i%%2]
echo"else: $0)"

Wandbox (with 42 instead of 4294967295)

Generated function:

proc(n:int)=echo(case n
of 0:"even"
of 1:"odd"
of 2:"even"
of 3:"odd"
of 4:"even"
...
of 4294967295:"odd"
else: $0)
\$\endgroup\$
1
  • \$\begingroup\$ @emanresuA, thank you, I've replaced my answer with valid solution. \$\endgroup\$ Commented Sep 25 at 4:53
2
\$\begingroup\$

Haskell, 105, 101 bytes

main=putStr$"main=interact$f.read"++do i<-[0..2^32-1];";f "++shows i"="++show(cycle["even","odd"]!!i)

-4 bytes thanks to xnor

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 101 bytes using do notation and cycle \$\endgroup\$
    – xnor
    Commented Sep 26 at 21:39
2
\$\begingroup\$

Python, 56 bytes

print({z:"eovdedn"[z%2::2]for z in range(2**32)},'.get')

Attempt This Online!

Returns None outside the defined range.

How?

Yet another variation on the idea by @xnor, @l2m4, @pxeger and @RichardJones.

\$\endgroup\$
3
  • \$\begingroup\$ There's a standard I/O post about mappings (i.e. dicts) being considered equivalent to functions (as long as they do in fact perform the equivalent task), so you could potentially omit the .get as well. \$\endgroup\$
    – emanresu A
    Commented Oct 2 at 22:55
  • \$\begingroup\$ @emanresuA Judging from the comments on that post there doesn't seem to be a strong consensus for or against it. \$\endgroup\$ Commented Oct 2 at 23:19
  • \$\begingroup\$ @emanresuA I take it a list - which technically is a mapping from the first few integers to the list's content - is definitely not allowed? Edit: If it would work which it doesn't. \$\endgroup\$ Commented Oct 3 at 3:46
1
\$\begingroup\$

Uiua, 42 41 bytes

⍥(:⊙:+1:&p◡$$ ⍥⋅"_"⊸=_
)ⁿ31 2"even"0"odd"

Try it: Uiua pad. Uses ⁿ5 2 (2^5) instead so it won't take forever.

Gives the source for a function of the form:

⍥⋅"even"⊸=0
⍥⋅"odd"⊸=1
⍥⋅"even"⊸=2
⍥⋅"odd"⊸=3
⍥⋅"even"⊸=4
⍥⋅"odd"⊸=5
⍥⋅"even"⊸=6
...
⍥⋅"odd"⊸=4294967295
\$\endgroup\$
2
  • \$\begingroup\$ does this work? you can't run each segment individually, because switch needs all of the branches before it in order to work properly \$\endgroup\$
    – nyxbird
    Commented Sep 25 at 20:58
  • 1
    \$\begingroup\$ @nyxbird See my new solution, which is nicely enough a byte shorter! \$\endgroup\$ Commented Sep 26 at 23:00
1
\$\begingroup\$

Python 2, 56 bytes

print"lambda n:'eovdedn'[n&1::2]*(n in",range(2**32),")"

Attempt This Online!

Python 3, 61 bytes

print("lambda n:'eovdedn'[n&1::2]*(n in",[*range(2**32)],")")

Attempt This Online!

Based on l4m2's answer

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

jbasher2, 395 bytes

this is actually SUPER SLOW. super rough calculations say that it will take somewhere around 15 DAYS to complete (when running in github codespaces)

create n with type number
create m with type number
create s with type string
parse 34 as char
set that to s
set 0 to n
while n < 4294967297
modulo n by 2
set that to m
output inline "if n == "
output n
output inline "output "
output inline s
if m == 0
output inline "even"
endif
if m == 1
output inline "odd"
endif
output s
output "endif"
add n by 1
set that to n
endwhile

jbasher2, 247 bytes

this one outputs 1 or 0 instead of even or odd, respectively

create n with type number
create m with type number
set 0 to n
while n < 4294967297
output inline "if n == "
output n
output inline "output "
subtract n by 1
modulo that by 2
output that
output "endif"
add n by 1
set that to n
endwhile
\$\endgroup\$
1
\$\begingroup\$

If we're using any version of Python from 3.6 onwards, we can eke out an extra character from some of the already-posted solutions with f-strings.

Python 3.8 (pre-release), 66 bytes

print(f"def f(n):n in{[*range(2**33)]}==print('eovdedn'[n&1::2])")

Try it online!

Based on l4m2's answer

Python 3.8 (pre-release), 60 bytes

I think this one might not be valid under the rules because the program itself doesn't print, it just returns something to print. But if it is...

print(f"lambda n:'eovdedn'[n&1::2]*(n in{[*range(2**33)]})")

Try it online!

Based on pxeger's answer

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Welcome to Code Golf, and nice first answer! The challenge spec allows printing the source code of a function, so both versions are valid. \$\endgroup\$
    – emanresu A
    Commented Sep 28 at 9:26
  • \$\begingroup\$ Oops - I'd misread the spec! Thanks \$\endgroup\$ Commented Sep 28 at 15:48
1
\$\begingroup\$

C# 8+ (.NET 6+), 132 bytes

Console.Write("n=>n switch{");for(uint i=0;i<int.MaxValue;)Console.Write($"{i*2}=>\"even\",{i++*2+1}=>\"odd\",");Console.Write("}");

Somewhat boring answer, but the best I can find in C#.

Outputs a lambda function taking a single arg n and containing a switch expression. Each segment of the switch maps a given n value to a given string, eg 1327=>"odd",. Note the trailing comma, as arms in a switch expression are comma-separated. A trailing comma at the end of the expression is valid .

The header segment is n=>n switch{, which defines the lambda function with a single expression body, and starts the switch expression. The tail segment is simply } to close the switch expression.

Outputs 2 segments at a time by only iterating up to Int32.MaxValue and outputting both the i*2 and i*2+1 segments simultaneously. This saves 1 byte over outputting each individual segment:

C# 8+ (.NET 6+), 133 bytes

Console.Write("n=>n switch{");for(uint i=0;i<uint.MaxValue;)Console.Write($"{i}=>\"{(i++%2==0?"even":"odd")}\",");Console.Write("}");

Does the same as above, but outputs each segment individually.

C# (.NET/.NET Framework), 136 bytes

Console.Write("n=>{");for(uint i=0;i<uint.MaxValue;)Console.Write($"if(n=={i})return\"{(i++%2==0?"even":"odd")}\";");Console.Write("}");

Outputs individual if statements, more faithful to the original challenge. This version should work on all language versions, as the switch expression was the only C# 8+ language feature used.

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

AWK, 75 bytes

END{for(i=0;i<2^32;)s=s"/"i"/{$0=\""(i++%2?"odd":"even")"\"}\n";print s"1"}

Try it online!

END{for(i=0;i<2^32;)           # 32 bits
s=s"/"i"/                      # appending to string s our number
{$0=\""                        # for the output
(i++%2?"odd":"even")"\"}\n";   # what will be printed
print s"1"}                    # will print $0


/4294967291/{$0="odd"}         # stdin is tested 
/4294967292/{$0="even"}        # for a string match
/4294967293/{$0="odd"}         # and upon which
/4294967294/{$0="even"}        # it modifies the
/4294967295/{$0="odd"}         # default output.
1                              # print $0 (default)

We're creating a huge string, so output is delayed. Testing with subsets works, though. We could save a byte by doing semicolons instead of new lines, but that doesn't seem quite in the spirit of the challenge.

\$\endgroup\$
1
  • \$\begingroup\$ In my opinion, semicolons would be entirely within the spirit of the challenge, but it's up to you. \$\endgroup\$
    – Wheat Wizard
    Commented Oct 29 at 16:48

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.