Raddoppia a modo tuo


31

Ci sono state un paio di sfide che coinvolgono il raddoppio del codice sorgente: qui e qui . Il compito che abbiamo qui è un po 'più difficile, ma dovrebbe essere fattibile in quasi tutte le lingue.

In questa sfida, prenderai un intero positivo arbitrario. Il tuo programma deve generare quell'intero raddoppiato . Quando il codice sorgente viene raddoppiato, prenderà un numero intero positivo e lo emetterà al quadrato .

Come viene raddoppiato il tuo codice sorgente? Bene, puoi farlo a modo tuo . Vale a dire, è possibile dividere il codice sorgente fino in stringhe di byte o caratteri (o gettoni in Langs tokenized) di qualsiasi uguale lunghezza desiderata , e ripetere ogni blocco due volte di seguito.

Per un programma iniziale di ABCDEFGHIJKL, (lunghezza 12) qui ci sono tutti i possibili programmi raddoppiati:

Chunk length |   Doubled source code
-------------+-------------------------
           1 | AABBCCDDEEFFGGHHIIJJKKLL
           2 | ABABCDCDEFEFGHGHIJIJKLKL
           3 | ABCABCDEFDEFGHIGHIJKLJKL
           4 | ABCDABCDEFGHEFGHIJKLIJKL
           6 | ABCDEFABCDEFGHIJKLGHIJKL
          12 | ABCDEFGHIJKLABCDEFGHIJKL

Si noti che ciò significa che i programmi di lunghezza primaria possono essere raddoppiati solo in due modi: ogni carattere raddoppia o l'intero programma viene ripetuto due volte.

Regole:

  • Il codice deve essere un programma o una funzione completi.
  • Sono vietate le scappatoie standard.
  • Sono consentiti metodi I / O standard.
  • Tutti i caratteri / byte, inclusi spazi bianchi e nuove righe, vengono conteggiati nella lunghezza del codice e contribuiscono ai blocchi.
  • Si può supporre che l'ingresso e la sua piazza possono essere rappresentati da tipo int / integer di tua lingua.
  • Non puoi assumere una nuova riga finale o un altro personaggio.
  • Fornisci la dimensione del blocco nell'intestazione dopo il conteggio dei byte.
  • Questo è , quindi i programmi più brevi sono meglio! Se due programmi hanno la stessa lunghezza, vince quello che utilizza la lunghezza del blocco più piccola. (Se hai un programma più lungo che utilizza una lunghezza del pezzo più piccola, vale la pena pubblicare anche questo!)
  • Se il tuo programma richiede un secondo input / riga, non puoi fare ipotesi sul suo valore. In particolare, il programma dovrebbe funzionare se il secondo input è vuoto, uguale al primo o un numero intero diverso. Se il programma non richiede un secondo input / riga, è possibile ignorare questa limitazione.

Link sandbox


Posso visualizzare il risultato come float (con .0alla fine)?
dice Val Reinstate Monica l'

Possiamo stampare il quadrato due volte quando il codice viene raddoppiato? Singolo codice: 5 -> 10; doppio codice: 5 -> 25 25.
Robin Ryder,

@RobinRyder No, non puoi.
GammaFunction

@val È possibile eseguire l'output come float.
GammaFunction

Risposte:


18

Perl 5 , 8 byte (dimensione del blocco 4)

$_*=~~+2

Provalo online o prova la versione raddoppiata .

Unario ~è il negato bit a bit, quindi applicarlo due volte è un noop. Pertanto, il programma di base si moltiplica semplicemente$_ (la variabile input-output implicita) per 2.

Binary ~~è smartmatch, che restituisce un valore booleano. ~~+2~~+2analizza come (~~+2) ~~ (+2). Poiché 2 è uguale a 2, questo produce true (1). Pertanto, il programma raddoppiato prima si moltiplica $_per 1, quindi si moltiplica $_da solo.


17

05AB1E , 4 byte (dimensione del blocco 2 o 4)

·Inr

Provalo online o raddoppiato come un singolo blocco da 4 byte o raddoppiato come due blocchi da 2 byte .

·        # double the implicit input
 In      # square the input
   r     # reverse the stack: it's now [input ** 2, input * 2]
         # if we stop here: implicitly output the top of the stack (input * 2)
·        # double the top of the stack (giving input * 4, not that it matters)
 In      # square the input
   r     # reverse the stack: it's now [input ** 2, input * 4, input ** 2]
         # implicitly the top of the stack (input ** 2)

15

Python 3 , 26 byte (dimensione del blocco 13)

lambda n:"and n*n#"and 2*n

Try it online!

raddoppiato:

lambda n:"andlambda d:"and n*n#"and 2*n n*n#"and 2*n

Questa soluzione è fornita da @Grimy.


Python 3 , 32 30 28 byte (dimensione del blocco 16 15 14)

lambda n:bool(0)*n*n or  2*n

Provalo online!

-4 byte grazie a @negativeSeven

raddoppiato:

lambda n:bool(lambda n:bool(0)*n*n or  2*n0)*n*n or  2*n

Provalo online!

The function takes advantage of the unique chunk rule of this challenge.


3
26: TIO
Grimmy

1
@Grimy Nice approach. I think it is different enough and deserves its own post.
Joel

1
@Grimy I added your solution to my post since you do not seem to be interested in making a separate post.
Joel

9

Befunge-98 (FBBI), 8 bytes (chunk length 2)

;&:#* +q

Try it online!

;&;&:#:#* * +q+q

Try it online! (doubled)

Excluding control flow, the first program executes &:+q (input, duplicate top of stack, add, exit with return code), and the second executes &:*+q (input, duplicate top of stack, multiply, add (sums with an implicit 0), exit with return code)


9

Hexagony, 14 bytes (chunk size 14)

?"+==*/}=+!@!<

Expanded:

  ? " +
 = = * /
} = + ! @
 ! < . .
  . . .

Try it online!

Doubled

?"+==*/}=+!@!<?"+==*/}=+!@!<

Expanded:

   ? " + =
  = * / } =
 + ! @ ! < ?
" + = = * / }
 = + ! @ ! <
  . . . . .
   . . . .

Try it doubled online!

Hexagony is in a bit of a weird position in this challenge, in that actually achieving the task is not much more difficult than simply being able to write the two individual programs. However, golfing the solution proved rather difficult.

This solution is the trivial idea in the shortest form that I could fit, but I suspect there are shorter, cleverer answers. This version very naively sets two values to the input and sums them or multiplies them, depending on if the source is doubled. The only code reuse is the "+ which makes making the copy code for the doubled program short enough to fit in the unused space from the original program.

I suspect using the IP change instructions [] will make isolating the parts easier, but a truly ideal solution will reuse a lot of code between the two. I made a helper program to double hexagony source code. Note that it removes trailing no-ops so if you want to have placeholder no-ops at the end just fill in some other character and change it back after. It can handle different chunk sizes, though I didn't yet write code to output each possible program (Hexagony seems to lend itself to using the full chunk size).


2
@JoKing Well done! It's rather different from my answer, so would you want to post it (using the different chunk size to fill up unused space is really neat!)? Otherwise I'll add it and an explanation when I have more time.
FryAmTheEggman

9

Hexagony, 12 bytes (chunk size 4)

?"2+...}=*!@

Try it online!

Formatted:

  ? " 2
 + . . .
} = * ! @
 . . . .
  . . .

And doubled, then formatted:

   ? " 2 +
  ? " 2 + .
 . . } . . .
} = * ! @ = *
 ! @ . . . .
  . . . . .
   . . . .

Basically, this sets the first edge to the input, then the second edge to either 2 or a copy of the input, then multiplies those two edges into the third edge, prints that and terminates. The list of executed instructions are just

?"2}=*!@

and

?"2+}=*!@

With the only difference being the + overriding the 2 on the second program.


8

JavaScript (ES6),  24  22 bytes

Despite its unusual format, this is the definition of an anonymous function, which can be either called directly or assigned to a variable.

+(g=x=>x*x)?g:(x=>x*2)

Try it online!

+(g=x=>x*x)?g:(x=>x*2)+(g=x=>x*x)?g:(x=>x*2)

Try it online doubled!

How?

Applying the unary + to a function is interpreted as an attempt to coerce it to a number and results in NaN. Therefore, the leading +(g=x=>x*x) is falsy in both versions.

On the other hand, applying the binary + between 2 functions results in a string. Therefore, (x=>x*2)+(g=x=>x*x) is truthy in the doubled version.


Dude, have you noticed that this can be split in chunks of 11, too?
Gust van de Wal

7

Perl 6, 8 bytes (chunk size 1)

* *<1 2>

Try it online! Try it doubled!

A Whatever/HyperWhatever lambda that takes a number and returns a number for the first program and a singleton list for the second program. Basically this keeps the exact same logic, except that the multiplication operator (*) is replaced by the exponential one (**).

**  **<<11  22>>

The Whatever literal (confusingly also represented by a *) are doubled up to a HyperWhatever (**) which is basically the same except it maps over lists. The space is needed to separate the Whatever literal from the multiplication and is ignored when doubled up. Instead of just 2 (which would get doubled to 22) we use a list containing two elements, which evaluates to 2 in a numeric context). The <> can be doubled to a list with interpolation, and the two elements inside are doubled, but neither of those change the length of the list.


6

Runic Enchantments, 9 bytes (chunk size 3)

i3?:*@:+@

Try it online!
Try it doubled!

The 3? skips the next 3 instructions, resulting in an (executed) i3?...:+@. When doubled it results in an executed i3?...:*@ where . represents the 3 NOP'd instructions. @ is "print entire stack and terminate."



5

Brain-Flak, 48 30 bytes (chunk size 10)

(({}))<>( {({}[()])}{}<>{}{}) 

Try it online! Try it doubled!

This basically takes three steps, then when doubled executes those steps twice each. The initial program is:

  1. Duplicate TOS, switch stacks and start pushing a value
  2. Get the TOS's triangular number n*(n-1)/2
  3. Pop TOS, switch stack and pop twice, then push the result.

For an input n into an undoubled program, this results in:

1.  Start stack: n n
    Other stack: <
    Third stack: 
2.  Start stack: n n
    Other stack: 0 <
    Third stack: tri(0) = 0
3.  Start stack: n+n+tri(0) = 2n <
    Other stack:
    Third stack:

For the doubled program:

1a. Start stack: n n
    Other stack: <
    Third stack: 
1b. Start stack: n n <
    Other stack: 0 0
    Third stack: 
2a. Start stack: n 0 <
    Other stack: 0 0
    Third stack: tri(n)
2b. Start stack: n 0 <
    Other stack: 0 0
    Third stack: tri(n)+tri(0) = tri(n)
3a. Start stack: n
    Other stack: tri(n) <
    Third stack: tri(n)
3a. Start stack: 0+n+tri(n)+tri(n) = n + 2*tri(n) = n + n*(n-1) = n*n <
    Other stack: 
    Third stack: 


4

Brain-Flak, 76 bytes, 76 byte chunks

({}<>)(()[([][()])]{(<{}{}({({})({}[()])}<>)<>>)}{}){{}(({})({})<>)(<>)}{}<>

Try it online!

Doubled (with newline for clarity)

({}<>)(()[([][()])]{(<{}{}({({})({}[()])}<>)<>>)}{}){{}(({})({})<>)(<>)}{}<>
({}<>)(()[([][()])]{(<{}{}({({})({}[()])}<>)<>>)}{}){{}(({})({})<>)(<>)}{}<>

Try it online!

Here is a version that uses a more complex doubling procedure. It does 5 chunks of size 15. The code here is 46 bytes however due to the required padding it is substantially longer.

105 90 bytes, 15 byte chunks

(              {<><({}()())><><><            <>>({})({}[()])}{}            )<>            

Try it online!

Doubled (with newlines for clarity)

(              (              
{<><({}()())><>{<><({}()())><>
<><            <><            
<>>({})({}[()])<>>({})({}[()])
}{}            }{}            
)<>            )<>            

Try it online!


4

Cubix, 18 14 bytes (chunk length 9 7)

*OI$|:/@O+:I. 

Note the trailing space. Try it online!

Doubled:

*OI$|:/*OI$|:/@O+:I. @O+:I. 

Again, there is one trailing space. Try it online!

Explanation

The main idea is that doubling the code causes the cube to become bigger, so the instruction pointer starts at a different symbol. Since the addition program cannot be put on a cube of side length 1, the side length is going to be 2. Additionally, the doubled code needs to be on a cube of side length 3, so the doubled code must be at least 25 bytes. This means the code must be at least 13 bytes long. As such, at most 1 more byte can be saved.

Now to the actual code. The first observation is that the top face (that is, the first 4 characters) are not used by the addition program. Furthermore, if we make the 5th character reflect the IP around the cube, we can free up 2 more characters. We will use these characters to put the squaring program.


4

Mornington Crescent, 656 Bytes (Chunk size 328)

Just to add weight to the theory that this can be solved in almost any language...

Take Northern Line to Bank
Take District Line to Bank
Take District Line to Parsons Green
Take District Line to Bank
Take District Line to Hammersmith
Take Piccadilly Line to Russell Square
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Hammersmith
Take District Line to Upminster
Take District Line to Embankment
Take District Line to Hammersmith
Take District Line to Upminster
Take District Line to Acton Town
Take District Line to Acton Town
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Bounds Green
Take Piccadilly Line to Leicester Square
Take Northern Line to Leicester Square
Take Northern Line to Mornington Crescent

(The trailing newline is important)

Try the single version! ...or... Try the doubled version!


This was a particularly tricky challenge in Mornington Crescent because the program must have such a rigid structure. It's also important to watch where the doubling would take place, because teleporting between stations is illegal in London.

The theory here is simple: In the single version, 'Bounds Green' is filled with a random string, but in the doubled version it gets filled with the squared input. After the chunk ends, both versions double the 'input', but in the doubled version of the code, the input has been replaced with 0.

This result is taken back to Bounds Green, which performs a max() operation twice, before taking the result to the output. In the single version this leaves the doubling unaltered (the int and string are just switched back and forth), but in the doubled version this replaces the 0 with the squared result already stored in Bounds Green.


If my explanation wasn't good enough, I suggest you visit London and try the two routes yourself.


Typo: your chunk size is 328 and not 326. Welcome to CGCC!
Robin Ryder

Nice spot, thanks!
Alevya

@JoKing Not sure how I missed that! As it is, I routed it so the 2nd half has no excess chars, and found a way to pad the first half to match without needing extra whitespace. Looks better this way anyway ;)
Alevya


3

R, 42 35 28 bytes (chunk size 4)

Now with a smaller chunk and no error. I also have a longer solution with chunk size 3; see below.

I don't think it is possible to write an R answer with chunk size 1 or 2; I'll happily give a bounty to anyone who proves me wrong.

s =scan#
n=s()# 
  
n/2*4#  

Try it online!

The # is for comments in R. The 3rd line is only spaces, making a chunk of newline + 2 spaces + newline, so that the previous and next chunk can have no newline.

Doubled, it becomes:

s =ss =scan#can#
n=s
n=s()# ()# 
  

  
n/2*n/2*4#  4#  

Try it online!

The single version computes n2×4=2n; the double version computes n2×n2×4=n2.

Here is a slightly longer solution, but with chunk size 3:

R, 39 bytes (chunk size 3)

s =bbb=scan#
n=s(#
 
)# 
n* 1/ 2/ 1* 4#

Try it online!

Doubled:

s =s =bbbbbb=sc=scan#an#
n=
n=s(#s(#
 

 
)# )# 
n*
n* 1/ 1/ 2/ 2/ 1* 1* 4# 4#

Try it online!

Note that Giuseppe has another R answer, with one chunk of 30 bytes.


3

R, 59 30 bytes (chunk size 59 30)

F=F+1;f=function(n)n*c(2,n)[F]

Try it online!

Credit to Robin Ryder for inspiring this; increments F each time, and the function f selects the appropriate output.

This isn't particularly interesting, but doubtless something clever manipulating the chunk size will be dreamed up. As expected, Robin Ryder came up with this which is both shorter and has some neat chunk manipulation.


2

PowerShell, 22 bytes (chunk size 11)

param($p)
#   /
2 * $p

Try it online.

Doubled:

param($p)
#param($p)
#   /
2 * $p   /
2 * $p

This solution is based on @ShieruAsakoto's solution.

@Grimy solution that has been converted to PowerShell, 26 bytes (chunk size 13)

param($p)$t=';$p*$p#';$p*2

Try it online.

Doubled:

param($p)$t=';param($p)$t=';$p*$p#';$p*2$p*$p#';$p*2

1
Unfortunately you need to have a chunk size that divides your code into equal chunks. As per example in question about prime length solutions.
John Rees

@JohnRees, i corrected my answer, thanks.
Andrei Odegov


1

Charcoal, 13 bytes

PI×Iθ⎇υIθ²⊞υω

Try it online! Explanation: The predefined empty list is falsey so the input is multiplied by 2. When doubled the second pass sees the empty string has been pushed to the list so it multiplies the input by itself instead. Try it online! In verbose syntax this corresponds to Multiprint(Cast(Times(Cast(q), Ternary(u, Cast(q), 2)))); Push(u, w);.



1

Java 8, 62 bytes

n->n*(Byte.SIZE>8?n:2);/*
class Byte{static int SIZE=9;}/**///

Chunk length 62.

Try it online or try it online doubled.

Explanation:

n->                    // Method with integer as both parameter and return-type
  n*                   //  The input, multiplied by:
    (Byte.SIZE>8?      //   If Byte.SIZE is larger than 8:
      n                //    Multiply by the input itself
     :                 //   Else:
      2);              //    Multiply by 2
class Byte{            // Class which overwrites Byte
  static int SIZE=9;}  //  And sets the SIZE to 9

In Java, the available comments are // comment and /* comment */. Which are combined here to overwrite certain parts. See how these comments work thanks to the Java highlighting:

n->n*(Byte.SIZE>8?n:2);/*
class Byte{static int SIZE=9;}/**///

n->n*(Byte.SIZE>8?n:2);/*
class Byte{static int SIZE=9;}/**///n->n*(Byte.SIZE>8?n:2);/*
class Byte{static int SIZE=9;}/**///

The doubled program created a custom Byte class and its value SIZE=9, which overwrites the default java.lang.Byte class and its value SIZE=8.


1

Japt, 7 5 bytes

*N²jJ

Try it | Doubled

² pushes 2 to the array of inputs N then j removes & returns the element at index J=-1 (i.e., the newly inserted 2) and multiplies the input by that.

When doubled it results in J being multiplied by 2, so the element at index -2 (i.e., the input) is returned by j and used as the multiplier.



1

Nice solution: Lua, 66 bytes (chunk size 66 bytes)

a,x=a and...^2 or ...*2,setmetatable(x or{},{__gc=load'print(a)'})

Try it online! (double it yourself, it is not so hard)

Oh yeah, pretty sure that there is shorter solution to this, but it's the best I was able to came up with this way. Take input as first argument.

Brief explanation: whole business with a is quite obvious for everyone, while the second part with x is more interesting. Basically, I create a table (or update existing one on second pass) with finalizer (__gc metamethod) which gets called when program exits.

Lame solution: Lua, 60 bytes (chunk size 30 bytes)

a=a and...^2 or ...*2;                     print(a)os.exit()

Try it online! or Try it doubled!

Smaller and with better chunking, but ultimately boring and lame without any clever tricks. I'm pretty sure no comments are required to this one.



1

J, 15 10 9 bytes

+: :(*-:)

Try it online!

Doubled version: Try it online!

f : g creates a verb that executes f when called with one argument, and g when called with 2 arguments. So ours executes double +: with the original source and *-: when the source is doubled.

This works because a train of two verbs in J becomes a hook, and thus f f is executed as y f (f y) where y is the original input. Additionally, *-: is itself a "dyadic hook" which works by multiplying * the left arg by half -: the right arg. The left arg will be the original input, and the right arg will be the input doubled, so this will produce the square of the original input.

original answer

J, 15 bytes

*:@]`(+:@])@.=~

Try it online!

Doubled version: Try it online!

In the single version, we have a single verb which uses Agenda @. to do the if... then logic: If the argument is equal to itself =~, then take the argument and double it (+:@[).

However, when we double the code, we get a J hook. Call the verb f and the input y. Then the hook f f executes like this:

y f (f y)

Which means that now the original input is the left arg, and the right arg is the doubled input. Since these will not be equal, =~ will return false this time, and now we'll execute the other fork of the Agenda, ie, *:@], which means "square the right arg." And since ~ reverses the inputs of a dyadic verb, the right arg will be the original input.


1

Python 3, 60 bytes

Chunk size 6.
Not a great solution, but it works. This is such a unique challenge, it really makes you think from a different perspective.

0;  i=input;0;  p=print;n=i()#
x=int(n)##
z=2*x#z=x*x
p(z)##

Try it online!

Doubled:

0;  i=0;  i=input;input;0;  p=0;  p=print;print;n=i()#n=i()#
x=int
x=int(n)##
(n)##
z=2*x#z=2*x#z=x*x
z=x*x
p(z)##p(z)##

Try it online!


1

Cascade, 13 bytes (chunk size 13)

]
&/2
#
*
 2&

Try it online!

]
&/2
#
*
 2&]
&/2
#
*
 2&

Try it doubled!

This was quite difficult. The basic gist of this is to print the input multiplied by 2 for the first program, and replace the 2 by a copy of the input for the second.

Explanation:

The executed part of the first program looks like

]     Redirection
 /
#     Print
*     The multiplication of
 2&   Input and 2 (wrapping around the left)

The doubled program basically adds the first ] to the end of the last line, so the program wraps around to that instead of the &. This turns it into

]     Redirection
 /
#     Print
*     The multiplication of
 2 ]  Set the value of
& 2   The variable '2' to the input
      Then multiply the result of that (input) by '2' (input)

0

Zsh, 30 bytes (chunk size 10)

m=$m[1]*2
x=$[$1$m]
return $x

Try it online! Try it doubled!

Abuses the fact that $var in $[$var] gets expanded first, then evaluated in the arithmetic context.

             # each line is 9 characters long. when doubled, each is run twice.
m=$m[1]*2    # first time: m='*2'   second time: $m[1] is '*', so m='**2'
x=$[$1$m]    # single: x=$[$1*2]    doubled: x=$[$1**2];x=$[$1**2].
return $x    # zsh supports 32-bit return values from functions, unlike bash

If anyone wants a crack at lowering this, here's the closest to a 24/8 solution I've gotten (outputs x^2+2 when doubled)

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.