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 oni'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 code-golf, the shortest generating program wins!
26 Answers 26
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(...).
-
2\$\begingroup\$ So, why 2**32+2, why not 2**33 \$\endgroup\$tsh– tsh2024年09月24日 08:49:08 +00:00Commented Sep 24, 2024 at 8:49
-
4\$\begingroup\$ @tsh I guess nothing does prevent claiming that all the extras are part of the footer, good point \$\endgroup\$xnor– xnor2024年09月24日 08:50:29 +00:00Commented Sep 24, 2024 at 8:50
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.
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}
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.
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];}
-
3\$\begingroup\$ 59 bytes using parameter unset assigned expansion Try it online! \$\endgroup\$Nahuel Fouilleul– Nahuel Fouilleul2024年09月25日 13:42:53 +00:00Commented Sep 25, 2024 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– hanshenrik2024年09月26日 08:38:00 +00:00Commented Sep 26, 2024 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\$Olivier Dulac– Olivier Dulac2024年09月26日 11:29:15 +00:00Commented Sep 26, 2024 at 11:29
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
-
2\$\begingroup\$ I think this works for 93 bytes. 1) use
?:instead ofif(){}boilerplate. 2) Explicitly declaringunsignedseems unnecessary. 3) Fixed bug whereif(x==0)was not emitted. \$\endgroup\$Digital Trauma– Digital Trauma2024年09月24日 19:48:05 +00:00Commented Sep 24, 2024 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 afteri(I think this might also be undefined behaviour) \$\endgroup\$SquareFinder– SquareFinder2024年09月24日 23:40:06 +00:00Commented Sep 24, 2024 at 23:40 -
2\$\begingroup\$ @DigitalTrauma in that case, you can neglect setting
i=0and do this instead for 92 bytes \$\endgroup\$SquareFinder– SquareFinder2024年09月25日 00:37:06 +00:00Commented Sep 25, 2024 at 0:37 -
2\$\begingroup\$ I think you need to specify
unsigned xin the generated code, right now any input above the signed integer maximum does not give any output (e.g. 4294967295) \$\endgroup\$SquareFinder– SquareFinder2024年09月25日 09:51:46 +00:00Commented Sep 25, 2024 at 9:51 -
2\$\begingroup\$ Alternative 92-byte solution assigns
iusing the otherwise wastedputs():f(i){for(i=!puts("g(x){");printf(....\$\endgroup\$Toby Speight– Toby Speight2024年09月26日 12:09:33 +00:00Commented Sep 26, 2024 at 12:09
JavaScript (Node.js), 57 bytes
for(a='x=>',i=0;a+=i+'==x?x%2?"odd":"even":',~i++;)_=>a+_
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])")
pog
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 ends4999999999 -> "odd"|>.
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
-
1\$\begingroup\$ You can save 13 bytes by rewriting the third line as
t='"even"';if(mod(n,2)>0)t='"odd"'. \$\endgroup\$Dingus– Dingus2024年09月24日 12:20:58 +00:00Commented Sep 24, 2024 at 12:20
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
-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
-
\$\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\$Digital Trauma– Digital Trauma2024年09月24日 17:16:27 +00:00Commented Sep 24, 2024 at 17:16 -
\$\begingroup\$ -39 bytes. Note more than one case per line should be OK \$\endgroup\$Digital Trauma– Digital Trauma2024年09月24日 17:53:45 +00:00Commented Sep 24, 2024 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 with2147483648out of curiosity, and it sat there for a few seconds before erroring so hard the terminal window disappeared. \$\endgroup\$Bbrk24– Bbrk242024年09月25日 00:17:25 +00:00Commented Sep 25, 2024 at 0:17 -
\$\begingroup\$ The largest power of two for which it doesn't error for me is
33554432. \$\endgroup\$Bbrk24– Bbrk242024年09月25日 00:22:55 +00:00Commented Sep 25, 2024 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\$Themoonisacheese– Themoonisacheese2024年09月25日 07:40:27 +00:00Commented Sep 25, 2024 at 7:40
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
-
\$\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/elserather than separateifstatements.) \$\endgroup\$Neil– Neil2024年09月25日 05:57:42 +00:00Commented Sep 25, 2024 at 5:57 -
\$\begingroup\$ Japt doesn't have
if(/else)statements, @Neil. The closest I could get to the spec would be to use logicalANDwith explicit output, which would be the same byte count. \$\endgroup\$Shaggy– Shaggy2024年09月25日 10:57:26 +00:00Commented Sep 25, 2024 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– Neil2024年09月25日 11:15:40 +00:00Commented Sep 25, 2024 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– Shaggy2024年09月25日 11:22:59 +00:00Commented Sep 25, 2024 at 11:22 -
1\$\begingroup\$ Fair enough, the ternary operator also counts as if/else for me, thanks. \$\endgroup\$Neil– Neil2024年09月25日 12:56:14 +00:00Commented Sep 25, 2024 at 12:56
Charcoal, (削除) 27 (削除ここまで) (削除) 26 (削除ここまで) 24 bytes
FXχχ« ́¿ ́=Iι ́θ§⪪evenodd4ι
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.
§⪪evenodd4ι
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.
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..
- Trailing
": Since we already open a{without closing it later on, it seems it can't handle an also open nested"without explicitly closing it, since it otherwise gives an error in thecreate_blockfunction. - †† With the
q, it seems to think there is still a string on the stack when it does the=, even though the potential"even"/"odd"is within the if-statement block that it cannot reach during execution. Also, the]ywould have already joined it together with the digits if that were the case anyway.. So not entirely sure why theqis necessary, but without it it'll give an error on all inputs in the range[0,4294967294]and will only succeed without errors for the max 4294967295 itself - or invalid inputs.
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
Brachylog, 38 bytes (very inefficient)
2^32-1⟦;["∧\"even\"|","∧\"odd\"|"]zwm2
Try it with 2^4 instead to see it working
Explanation
2^32-1⟦ Take the list [0, 1, ..., 2^32 - 1]
;["∧\"even\"|","∧\"odd\"|"]z Circular zip with ["∧\"even\"|","∧\"odd\"|"]
wm2 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^16&g×ばつ2gj+1t;["∧\"even\"|","∧\"odd\"|"]zwm2⊥
Explanation
2^16>N Take a number I between 0 and 2^16
×ばつ2 J = I ×ばつ 2
gj+1t [J, J + 1]
;["∧\"even\"|","∧\"odd\"|"]z Zip J with "∧\"even\"|" and J+1 with "∧\"odd\"|"
wm2 Write everything
⊥ False: this will force to retry write with different values of J
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".
Jelly, (削除) 18 (削除ここまで) 16 bytes
Ø%ŻṾ)fị"£Ƙ®"4Ḍ»Ṿ
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,
- e.g. the \174ドル\$th segment, for \$i=173\$, is
- 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..232-1]
0,1,2,3,...4294967295,4294967296 - list of integers -> [0..232]
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..232-1]
<i>,4294967296 - list of integers -> [i..232]
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ị"£Ƙ®"4Ḍ»Ṿ - Main Link: no arguments
Ø% - 232
Ż - zero range -> [0..232]
Ṿ - unevaluate -> "0,1,2,...,4294967296"
- implicit print
)fị - list of characters -> "fị"
- implicit print
"£Ƙ®"4Ḍ» - list of lists of characters -> ["odd", "even"]
Ṿ - unevaluate {that} -> ""odd"even""
- implicit print
-
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/elserather than separateifstatements.) \$\endgroup\$Neil– Neil2024年09月25日 05:58:24 +00:00Commented Sep 25, 2024 at 5:58 -
\$\begingroup\$ @Neil it depends on your definition of "direct". As an example
"4Ḍ"£Ƙ®»Ṿ€;€)ḷ$)=¡ṭⱮṁØ%J’ż@Ɗ(28 bytes, but may be improbable - replaceØ%with32to 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\$Jonathan Allan– Jonathan Allan2024年09月25日 12:11:25 +00:00Commented Sep 25, 2024 at 12:11 -
\$\begingroup\$ *improbable -> improvable. (Same for 26 with
"4Ḍ"£Ƙ®»Ṿ€"ḷ$=¡"ṭⱮṁ32J’ż@Ɗ) \$\endgroup\$Jonathan Allan– Jonathan Allan2024年09月25日 12:48:19 +00:00Commented Sep 25, 2024 at 12:48 -
\$\begingroup\$ Thanks, as long as the code only prints
oddorevenfor those sections that have been included then that seems to be reasonable. \$\endgroup\$Neil– Neil2024年09月25日 13:00:35 +00:00Commented Sep 25, 2024 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– Shaggy2024年09月26日 23:43:57 +00:00Commented Sep 26, 2024 at 23:43
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("}");}
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.
-
1\$\begingroup\$ I think you can change three of those
printftoputs. \$\endgroup\$Neil– Neil2024年09月24日 16:31:55 +00:00Commented Sep 24, 2024 at 16:31 -
\$\begingroup\$ (then reads the next answer, which has done exactly the same thing...) \$\endgroup\$Neil– Neil2024年09月24日 16:32:24 +00:00Commented Sep 24, 2024 at 16:32
-
\$\begingroup\$ @Neil thanks, I knew I was forgetting something \$\endgroup\$SquareFinder– SquareFinder2024年09月24日 23:31:21 +00:00Commented Sep 24, 2024 at 23:31
-
1\$\begingroup\$ I didn't realise that g++ allows
f()with no return type. That's very permissive! \$\endgroup\$Toby Speight– Toby Speight2024年09月26日 12:04:51 +00:00Commented Sep 26, 2024 at 12:04
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.
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ドル)
-
\$\begingroup\$ @emanresuA, thank you, I've replaced my answer with valid solution. \$\endgroup\$janAkali– janAkali2024年09月25日 04:53:34 +00:00Commented Sep 25, 2024 at 4:53
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
-
1
Python, 56 bytes
print({z:"eovdedn"[z%2::2]for z in range(2**32)},'.get')
Returns None outside the defined range.
How?
Yet another variation on the idea by @xnor, @l2m4, @pxeger and @RichardJones.
-
\$\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
.getas well. \$\endgroup\$emanresu A– emanresu A2024年10月02日 22:55:59 +00:00Commented Oct 2, 2024 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\$Albert.Lang– Albert.Lang2024年10月02日 23:19:41 +00:00Commented Oct 2, 2024 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\$Albert.Lang– Albert.Lang2024年10月03日 03:46:55 +00:00Commented Oct 3, 2024 at 3:46
Uiua, (削除) 42 (削除ここまで) 41 bytes
⍥(:⊙:+1:&p◡$$ ⍥⋅"_"⊸=_
)n31 2"even"0"odd"
Try it: Uiua pad. Uses n5 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
-
\$\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– nyxbird2024年09月25日 20:58:31 +00:00Commented Sep 25, 2024 at 20:58
-
1\$\begingroup\$ @nyxbird See my new solution, which is nicely enough a byte shorter! \$\endgroup\$noodle person– noodle person2024年09月26日 23:00:16 +00:00Commented Sep 26, 2024 at 23:00
Python 2, 56 bytes
print"lambda n:'eovdedn'[n&1::2]*(n in",range(2**32),")"
Python 3, 61 bytes
print("lambda n:'eovdedn'[n&1::2]*(n in",[*range(2**32)],")")
Based on l4m2's answer
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
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])")
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)]})")
Based on pxeger's answer
-
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– emanresu A2024年09月28日 09:26:24 +00:00Commented Sep 28, 2024 at 9:26
-
\$\begingroup\$ Oops - I'd misread the spec! Thanks \$\endgroup\$Richard Jones– Richard Jones2024年09月28日 15:48:04 +00:00Commented Sep 28, 2024 at 15:48
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.
AWK, 75 bytes
END{for(i=0;i<2^32;)s=s"/"i"/{0ドル=\""(i++%2?"odd":"even")"\"}\n";print s"1"}
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.
-
\$\begingroup\$ In my opinion, semicolons would be entirely within the spirit of the challenge, but it's up to you. \$\endgroup\$2024年10月29日 16:48:32 +00:00Commented Oct 29, 2024 at 16:48
Explore related questions
See similar questions with these tags.
if (input == 0) print("even"); if (input == 1) print("odd"); ...it would beif (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\$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\$