Neanche ... Ho solo dispari!


36

Il tuo compito è semplice: scrivi un programma che riceve un numero intero come input e lo emette se era dispari, e non fa diversamente (non è consentito arrestare). La sfida è che puoi usare solo byte dispari.

È possibile aggiungere facoltativamente una nuova riga finale all'output.

Questo è code-golf, vince la risposta più breve in byte (dispari).

Sono vietate le scappatoie standard . Inoltre, non è possibile utilizzare versioni di lingue più recenti rispetto alla pubblicazione di questa sfida.

Esempio di input> output:

13 > 13

42 >


10
Ho declassato questa sfida perché è una sfida "Do X senza Y".
Leaky Nun,

4
Cosa does nothing otherwisesignifica esattamente ? In Haskell una funzione con tipo Int -> Int o restituisce un numero intero o non si ferma o genera un errore. Se l'input è pari, ovviamente non dovrebbe essere restituito, quindi non sarebbe accettabile arrestare o lanciare un errore in questo caso?
Laikoni,

2
Se vuoi sapere se puoi usare il tuo codice sorgente, prova questi script nella tua console del browser. Creare charset valida: alphabet=new Set(Array(256).fill(0).map((v,i)=>i).filter(v=>v%2).map(String.fromCharCode));. Controllare se la sorgente è valida: [..."SOURCE CODE"].every(v=>alphabet.has(v)). Vedi caratteri non validi in fonte: [...new Set("SOURCE CODE")].filter(v=>!alphabet.has(v)). Ricorda di sfuggire alle tue citazioni, "=> \";)
kamoroso94,

14
@LeakyNun "do X senza Y" non fa riferimento a sfide generali a fonte limitata , ma a sfide che ti vietano di utilizzare determinate funzionalità di una lingua. Questa sfida non è questa e non ha neppure dei problemi che rendono problematiche le sfide "do X without Y".
Martin Ender,

1
@Laikoni Poiché ci sono già alcune risposte che vanno in un ciclo infinito, direi che va bene mostrare un simile comportamento. Il non ritorno può essere interpretato come non fare nulla.
M.Herzkamp,

Risposte:



67

Lenguage , 645529908926937253684695788965635909332404360034079 9394157991500940492270727190763049448735 1174269748937617561533841898064735499551 22933829320200755

È approssimativamente uguale a 2 duodecilioni di byte.

Il file si traduce nel seguente programma brainfuck:

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

Accetta input come codice ASCII, con un valore massimo di 256. Utilizza il wrapping.


@Okx Il mio errore. Ma perché non usi semplicemente ,[<<+>+>-]<[>>+<<-]+>>[-[->]<]<[<[<]>.<]?
user202729

1
Che ne dici ,[[>]++[-<]<+>>]>[<<<.<]di soli 3452857532394791089951 byte?
Jo King,

In realtà, poiché sono consentiti loop infiniti, ,-[-->++<]>+.funziona anche
Jo King il

20

x86-64 Codice macchina, 8 byte

Ispirato alla soluzione di Bruce Forte , ma leggermente alla pari. :-)

8D 07          lea      eax, [rdi]    ; put copy of input parameter in EAX
D1 EF          shr      edi, 1        ; shift LSB into CF
             InfiniteLoop:
F3 73 FD       rep jnc  InfiniteLoop  ; test CF; infinite loop back here if input was even
C3             ret                    ; return with original input in EAX if it was odd

Nel EDIregistro viene preso un singolo parametro intero , seguendo la convenzione di chiamata AMD64 di System V.

Una copia di questo valore viene inizialmente creata e inserita EAX modo che possa essere restituita, se del caso. ( LEAè usato al posto del normale MOVperché abbiamo bisogno di un'istruzione con byte dispari.)

Quindi, il valore in EDIviene spostato a destra di 1, il che posiziona il bit spostato nella bandiera carry (CF). Questo bit sarà 0 se il numero era pari o 1 se fosse dispari.

Quindi testiamo CF usando il JNC istruzione, che si dirama solo se CF è 0 (cioè, il numero era pari). Ciò significa che entreremo in un ciclo infinito per valori pari. Per valori dispari, cadiamo e EAXviene restituito il valore originale (in ).

Però c'è un piccolo trucco con l' JNCistruzione: ha un REPprefisso! Normalmente, i REPprefissi vengono utilizzati solo con le istruzioni di stringa, ma poiché entrambi i manuali Intel e AMD concordano che irrilevante / superfluo / ridondanteREP prefissi vengono ignorati, ne lanciamo uno sulle istruzioni del ramo per renderlo lungo 3 byte. In questo modo, anche l'offset relativo che viene codificato nell'istruzione jump è dispari. (E, naturalmente, REPè esso stesso un prefisso a byte dispari.)

Grazie a Dio RET è codificato usando un byte dispari!

Provalo online!


Nel caso in cui non pensi di restituire il valore se è dispari o andare in un ciclo infinito se è pari (in modo da non tornare mai) soddisfa i requisiti di "output" della sfida, o vuoi solo qualcosa di più interessante, ecco una funzione che genera il valore su una porta seriale (ma solo se è dispari, ovviamente).

x86-64 Codice macchina (output su porta seriale), 17 byte

8D 07         lea   eax, [rdi]   ; put copy of input parameter (EDI) in EAX

B1 F7         mov   cl, 0xf7     ; put 0xF7 into low-order bits of CX
B5 03         mov   ch, 0x03     ; put 0x03 into high-order bits of CX
FE C1         inc   cl           ; increment low-order bits of CX to 0xF8 (so all together it's now 0x3F8)
0F B7 D1      movzx edx, cx      ; move CX to DX ("MOV DX, CX" would have a 16-bit prefix of 0x66)

D1 EF         shr   edi, 1       ; shift LSB of input parameter into CF
73 01         jnc   IsEven       ; test CF: branch if 0 (even), fall through if 1 (odd)
EF            out   dx, eax      ; output EAX (original input) to I/O port 0x3F8 (in DX)
            IsEven:
C3            ret                ; return

Ciò che rende questo un po 'più interessante è che il codice fa di più , il che significa che è stato più difficile fare tutto usando le istruzioni che sono codificate usando solo byte dispari. Ovviamente, questo significa anche che fallisce nel golf del codice, quindi è una specie di compromesso: vuoi essere interessante e stimolante o vuoi in breve?

Comunque, questo usa l' OUTistruzione x86 per scrivere sulla porta I / O 0x3F8, che è la porta seriale COM1 standard su un PC. La parte divertente, ovviamente, è che tutte le porte I / O standard (seriale e parallela) hanno indirizzi pari, quindi non possono essere semplicemente codificate come immediate perOUT istruzione o spostate direttamente in un registro. È necessario inizializzare con uno in meno del valore effettivo e quindi incrementare il valore nel registro. Sei anche limitato all'uso di determinati registri per la manipolazione perché hai bisogno di registri che sono codificati usando byte dispari nell'istruzione quando usati come operandi.

Inoltre, ho dovuto inizializzare il DXregistro (tramite il CXregistro) nella parte superiore del ciclo, anche se ciò è necessario solo se il valore è dispari, per garantire che l' JNCistruzione avrebbe uno scostamento dispari. Tuttavia, poiché ciò che stiamo saltando è l' OUTistruzione, tutto questo codice fa è cicli di scarto e registri dei graffi di clobber; in realtà no uscita nulla, quindi non si rompe le regole.

Infine, questa funzione tornerà (dopo aver eseguito o meno l'output sulla porta seriale) con il valore di input lasciato in EAX. Ma ciò in realtà non infrange alcuna regola; tutte le funzioni nel linguaggio assembly torneranno con un valore in EAX— la domanda è solo se è un valore significativo o un valore di immondizia . Ciò è determinato dalla documentazione della funzione (essenzialmente, restituisce un valore o restituisce void) e, in questo caso, lo sto documentando come non restituendo un valore. :-)

Nessun collegamento TIO per questo, in quanto non implementa l'output alle porte seriali. Avrai bisogno di ferro vero o di un'immaginazione.


+1 per la spiegazione! Perché puoi usare mov nella seconda riga ma non nella prima?
M.Herzkamp,

Oltre alla codifica che è MOVun'istruzione, i suoi operandi devono anche essere codificati nei byte. In questo caso, sarebbero i registri di origine e destinazione (sebbene gli operandi possano anche essere valori immediati, che sono come costanti). Registri diversi vengono associati a byte diversi e alcuni di questi byte sono pari. Quindi, per esempio, quello che vorrei usare sarebbe mov eax, edi, ma questo è 89 F8in byte. Vedi molto più di quanto tu abbia mai voluto sapere sulle codifiche qui, nella sezione "codice" . @ M.Herzkamp
Cody Grey,


9

05AB1E , 3 byte

Éi=

Il codice corrisponde ai valori byte C9,69,3Do 201,105,61che sono tutti dispari.

Provalo online!

Spiegazione

É     # input % 2 == 1
 i    # if true
  =   # print without popping

= # print without newline that's actually print with newline without popping
Erik the Outgolfer

@EriktheOutgolfer: True. I'll fix the explanation.
Emigna

Unfortunately, É× doesn't seem to work ):
kalsowerus

@kalsowerus: Yeah, I noticed that as well. Works correctly with a D in front, but that's even and not any shorter. The reason it doesn't work is that the repeated implicit input is taken as 2nd argument.
Emigna

@Emigna but the weird thing is, swapping the top two values on the stack twice, makes it work as well...
kalsowerus

5

MATL, 3 bytes

o?G

MATL uses ASCII characters, so o?G corresponds to bytes (in decimal) 111, 63, 71.

Try it online!

Explanation

o     % Push (implicit) input modulo 2
?     % If nonzero
  G   %   Push input
      % End (implicit)
      % Display stack contents (implicit)

5

Haskell, 36 33 bytes

c[1]=1;c[m]=1+1+c[m-1-1];o	m=c[m]

Try it online!

Usage: o 7 yiedls 7, o 8 enters an infinite loop.

The actual algorithm is

o 1 = 1
o m = 2 + o(m-2)

The first problem I faced was the lack of space and (, because a function o which takes an argument m is usually defined as o m=... or o(m)=.... However I found out that an inline comment {- some comment -} works as token delimiter too, so a definition o{--}m=... is possible under the given rules. Edit: Ørjan Johansen pointed out that one can use a tab character instead of a space, saving three bytes: o m=...

The second problem was the recursive call o(m-2). -2 is just -1-1, but here the comment trick does not work because the parentheses are required. I fixed this by letting the function work on a singleton list containing a number: o[m-2], however, as this is not a standard way of providing input, I outsourced the computation to a helper function c which works on lists and call c from o which has the correct format.


You can use a tab instead of a space.
Ørjan Johansen

@ØrjanJohansen I can verify that it works with \t instead of {--}.
Esolanging Fruit

@ØrjanJohansen Thanks, that's good to know.
Laikoni

5

Python REPL, 38 bytes

Takes input as the value of the previous expression using _. Output will be a string (the string representation of the integer for odd, or the empty string for even).

'%s'%[['']+[_]][-1][[_%[1+1][-1]][-1]]

Try it online

To run it in an actual shell, you can try it here. Type the input, hit enter. Paste the code, hit enter.

Explanation:

This took a while to figure out. There's no multiplication, no branching, no slicing, no commas, no periods, no imports, no parentheses, no exec, no eval, no print, and no functions. I got one solution working that output using stderr, but then I realized we had to output the actual integer, not just a truthy/falsey value.

I use brackets in place of parentheses with [expression][-1]. Simplifying that turns the above code into '%s'%(['']+[_])[_%(1+1)].

Since there can be no commas, I used list addition to create ['',_]. Using string formatting, the desired result is obtained.


Kudos. As a bonus, it also works for Ruby IRB :) Nitpick: is it okay to return a string for odd numbers, is it okay to return an empty string for even numbers?
Eric Duminil

Doing nothing and printing or returning nothing are the same, I'd think. In a way, empty string is nothing.
mbomb007

Yes, I was really nitpicking. It still returns a string instead of nothing. In Python REPL, I'd say that None would be an even better match than ''. Anyway, that's still 10000 times better than anything I could come up with.
Eric Duminil

@EricDuminil I could return False. Idk how you could get None, though.
mbomb007

4

CJam, 6 bytes

q_iY%%

113 95 105 89 37 37

This program takes the mod 2 of the input (call it r) and prints every r th character in the input string. If the input number is odd, it prints the whole string, but if asked to print every 0th character the program throws an error.

Try it here


Nice! I was going to post qi_Y%]W%{}/M? and then I saw this.
Esolanging Fruit

4

Cubix, 23 19 17 bytes

;;u!I1)%/;O=!;;/;

Try it!

@, which terminates a Cubix program, is ascii 64, so unfortunately this actually just enters an infinite loop after testing for oddness. No TIO link since it'll time out.

= (ascii 61) is a no-op in Cubix.

This is a slight modification of the prior algorithm (same # of bytes) that actually works for negative integers.

Cube version:

    ; ;
    u !
I 1 ) % / ; O =
! ; ; / ; . . .
    . .
    . .

Algorithm:

  • I (73) : read in input as number
  • 1 (49) : push 1
  • ) (41) : increment
  • % (37) : take the mod
  • / (47) : turn left
  • ! (33) : skip next instruction if odd
    • 1;;/; ; is (59) : prepares the stack for output
    • O (79) : Output as a number.
    • Then it re-enters the algorithm but I reads a 0 for end of input, so we are guaranteed to enter the even branch
  • u (117) : right-hand u-turn
  • ;;;!I : loop, effectively doing nothing.

@MickyT that fails for negative input, which is why I avoided using ?
Giuseppe

Apologies, I didn't check it properly
MickyT

3

Charcoal, 9 bytes

¿﹪Iθ÷χ⁵→θ

Try it online!

Basically it prints rightwards the input if it is not a multiple of 10/5 (the ² char is even in the Charcoal code page). The characters used are:

  • ¿: code BF.
  • : code A5.
  • : code C9.
  • θ: code F1.
  • ÷: code AF.
  • χ: code E3.
  • : code B5.
  • : code 13.

In fact the near the end is redundant but then I saw that the answer had to have an odd length...

Explanation:

¿      if (
 ﹪      Modulo (
  Iθ      the input as number,
  ÷χ⁵      χ (predefined value: 10) divided by 5 = 2 ) [is 1])
 →θ      then print rightwards the input as string

You're printing and then moving right; print rightwards would actually be →θ.
Neil

@Neil oops, fixed. At least that didn't invalidate my answer... :-D
Charlie

3

x86_64 machine code (Linux), 12 11 bytes

Unfortunately 0x80 is even, but it still worked out (assuming "does nothing" means not to return):

0000000000000000 <odd>:
   0:   8d 07                   lea  (%rdi), %eax
   2:   83 e7 01                and    $0x1, %edi
   5:   83 ff 01                cmp    $0x1, %edi
   8:   75 fb                   jne       5  <odd+0x5>
   a:   c3                      retq

-1 byte, thanks @CodyGray!

Try it online!


1
Since this is x86-64, lea (%edi),%eax requires an address size override prefix (0x67) when the source is a 32-bit register. You can eliminate that by doing lea (%rdi),%eax. That saves a byte, and actually would make the code slightly more efficient (prefixes slow down decoding and fill up i-cache). There are some other things you can do to shorten this even more, but that essentially constitutes a complete rewrite, so I'll post my own answer. :-) I've upvoted this, too, of course! (Oh, just realized you may have used the prefix to make the jump offset odd. Well, you'll need more magic.)
Cody Gray

Also, really clever solution for TIO! I've been skipping it in most of my asm answers because I didn't want to write all of the boilerplate in the "footer" to print output in asm. I finally broke down and did it the other day, but this is a much better idea, allowing you to use C for everything else. I'll be stealing this from now on! :-)
Cody Gray

Cheers for your inputs, I'm a complete noob at assembly but this seemed easy enough! Curious for your solution. Oh, credit goes to @ceilingcat - I stole it myself ;)
ბიმო

I didn't actually save you a byte… What you have now has an even byte (F6) for the JNE instruction because it has an even offset. That's what I meant by the last parenthetical I edited into my first comment. You actually need that prefix to create an odd alignment. Or you have to rewrite the code in some other way. I played with a bunch of different variations. I actually looked at this last night and was trying to figure out a good way to use OUT to output odd values, but no good solutions really occurred to me. The insight here for me is to go into an infinite loop for even values.
Cody Gray

This is a pretty silly challenge, actually, because none of the reasonable solutions work. It really just tests how well you know the obscure corners of the x86 instruction set. I even tried the BT family of instructions, which nobody uses ever (unfortunately, all register encodings are even bytes). I thought it might be more interesting to write code that output to a serial port, rather than just returning a value or whatever, but that does jack the byte count up there (especially since serial port addresses in hex are even!), so I gave up on it.
Cody Gray

3

Mathematica, 20 bytes

Appear to be the first solution in non-golfing language.

a=1+1;g[i_/;!a\[Divides]i]=i

In MacintoshChineseTraditional character encoding. \[Divides] is {161, 253} (2 bytes)

Alternative version (23 bytes)

\[CapitalAlpha]=1+1;\[CapitalGamma][\[CapitalChi]_/;\[CapitalAlpha]\[LeftFloor]\[CapitalChi]/\[CapitalAlpha]\[RightFloor]\[NotEqual]\[CapitalChi]]=\[CapitalChi]

or (shown in Unicode)

Α=1+1;Γ[Χ_/;Α⌊Χ/Α⌋≠Χ]=Χ

in Symbol character encoding. (use only 1-byte characters)

The solution defines a function g (or Γ) that, evaluate to input when the input is odd, and literally "do nothing" (does not evaluate) when the input is even.


+1 byte (; at the end) if the number of byte must be even; and \[Divides] also have odd Unicode codepoint.
user202729

You don't need I[1+1], you can just use {1+1}. Also, have you checked whether the bytes of the flooring brackets are valid? If so, you can obtain 2 from \[LeftFloor]E\[RightFloor].
Martin Ender

@MartinEnder Only Symbol make floor valid, but it has neither E nor \[ExponentialE].
user202729

I'm afraid you aren't allowed to use the characters D; v; nor d, since they have an even byte-value.. :(
Kevin Cruijssen

1
@KevinCruijssen \[Divides] is one single character in Mathematica, which is represented by 2 bytes {161, 253}.
user202729

3

Perl, 54 bytes

Requires -E.

I really really enjoyed this challenge, I think I'd like to try and improve this answer, but I think that's might be the shortest I can make for now. I've been playing with these answers on and off for a few days now, but feel I'm happy with the 54 byte solution!

s//A_=Y[;A_=A_%O?A_W''/;y/#A-_/#-A/;s/[#-}]+/uc/ee;say

Try it online!

Explanation

By default, most of Perl's string functions work on $_, which is empty to start.

First, s//A_=Y[;A_=A_%O?A_W''/ replaces the empty string in $_ with A_=Y[;A_=A_%O?A_W'', then y/#A-_/#-A/ replaces characters based on the following list (char above becomes char below):

#ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
#$%&'()*+,-./0123456789:;<=>?@A

which updates $_ to contain $_=<>;$_=$_%2?$_:''. Next s/[#-}]+/uc/ee replaces all chars [#-}]+ with uc. Without the /ee this would just be the string uc, but /ee evaluates the contents of the string twice. The first evaluation returns the result of uc, which is an uppercase version of $_ but since $_ contains no alphabetic characters, this just returns the whole string, then the second /e evaluates the string again, which sets $_ to either $_ (the input number) or '' depending on whether or not the number is odd or even.

Finally, since $_ now contains what we want, we call say (which is what requires -E instead of -e) which prints $_ followed by a newline.


Alternative Perl, 93 bytes

92 bytes code + 1 for -p, which I feel would make it non-competing.

s//_/g;s//uc/e;y/\x09-\x0b/_/;s/____/}[/;s/___/%C]/;s/_/{''H/;y/'{}1CDGH/'-)1-3+--/;s/[#-}]+/uc/ee

Contains a tab and a vertical tab in the y///, indicated as \x09 and \x0b.

Try it online!


2

LOGO, 390 46 52 50 bytes

[ask    1   se[make]iseq    1-3 cos ?/ask   1[1/sum 1   179]?]

That is a template-list that return the input if the input is odd, and cause an error if the input is even.

Usage:

show invoke [ask ... (paste code here) ... ] 5

output

5

since 5 is odd, and

invoke [ask ... (paste code here) ... ] 6

will cause an error because 6 is even.



2

TI-BASIC, 14 bytes

Input Q
sinֿ¹(gcd(Q²,int(e
Q

This throws a domain error (printing nothing to the homescreen) on an even number.

Input Q             Q is a variable with an odd code. We cannot use "Ans" as it's even.

            int(e   floor(e) = 2; "2" is even.
         Q²         Q may be negative, so we square it which preserves parity.
     gcd(Q²,int(e   1 if Q is odd; 2 if Q is even.
sinֿ¹(gcd(Q²,int(e   Error iff Q is even.

Q                   If there was no error, print Q.


1

Japt, 4 bytes

u)çU

Japt uses ISO/IEC 8859-1, so this corresponds to (in decimal) 117 41 231 85.

Test it online!

Explanation

Uu)çU   Implicit: U = input integer
Uu)     Return Python-style U % (missing argument = 2). This gives 1 if U is odd, 0 if even.
   çU   Implicitly convert U to a string and repeat it that many times.
        Implicit: output result of last expression

I first tried solutions using p, which is basically ç with reversed arguments. However, p performs exponentiation if its left argument is a number, so we'd need to explicitly convert it to a string. This solution turns out to actually be a byte shorter, in addition to not containing any odd bytes.


1

dc, 21 bytes

[c]sa?kKKCI-1;1k%1!=a

Decimal: 91 99 93 115 97 63 107 75 75 67 73 45 49 59 49 107 37 49 33 61 97

As per this IO default, this program leaves the input on the main stack if it is odd and empties the stack otherwise. This can be confirmed by adding the f debug command to the end of the program as is the case on the TIO page.

Try it online!

Explanation

[    # Begin macro definition.
 c   # Clear the main stack.
]sa  # End macro definition and push the macro into register "a".
?k   # Prompt for input and store it into precision parameter "k".
KK   # Push two copies of the input to the main stack.
CI-  # Push C-I = 12-10 = 2 to the main stack  
1;1  # Push the value stored in the first index of array "1" (0 by default) 
     # to the main stack. 
k    # Push 0 into parameter "k" to reset the precision (otherwise the modulus 
     # function will not work correctly).
%    # Push the input (mod 2) to the main stack.
1!=a # If the input (mod 2) does not equal 1, execute the macro in register "a".
f    # OPTIONAL: Output the contents of the main stack.

1

TI-Basic, 18 bytes

Saved 2 bytes thanks to lirtosiast

:Prompt Q
:While 5Q/ᴇ1-int(5Q/ᴇ1
:Q

in bytes (+2 newlines = 3F)

:Prompt Q
 DD     51
:While 5Q/ᴇ1-int(5Q/ᴇ1
 D1    35 3B B1  35 3B  
        51 31     51 31
         83 71     83
:Q
 51

See http://tibasicdev.wikidot.com/one-byte-tokens


1
Why not use fPart(?
lirtosiast

@lirtosiast seems to be an even byte (BA = 186) according to tibasicdev.wikidot.com/one-byte-tokens
Oki

Oh, I misread which entries were rows and which are columns.
lirtosiast

1
I found Input Q[newline]sinֿ¹(gcd(Q²,int(e[newline]Q (14 bytes). May I post as separate answer?
lirtosiast

@lirtosiast Wow! It's definitely different enough for a seperate answer. Love it
Oki


0

Bash, 31 bytes

read a
[ $[a%2] = 0 ] ||echo $a

Try it online!

Explanation:

read a                   reading the input and define it on the variable a
[ $[a%2] = 0 ]      outputs exit status 0 when a/2 is 0 and exit status 1 if not.
||                           evaluates only when the exit status left of it is 1
echo $a                displays the variable a

You seem to have missed that this is a restricted source challenge - you are using forbidden bytes. (rd $20|h and newline.)
Ørjan Johansen

@ØrjanJohansen fixed I guess
ADDB

2
Um no. There is no restriction on the length of the program, but every character in it must have an odd byte value.
Ørjan Johansen
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.