J'ai trouvé une question sur le site Code Review qui semble intéressante. Je pense qu'OP ne le fait pas correctement, mais je ne peux pas en être sûr ... Alors résolvons-le pour lui! (écrire un programme, pas une fonction / procédure)
Entrée (stdin ou similaire):
Un entier x
en notation décimale. Il est supérieur à 1 et inférieur à 2 ^ 31.
Sortie (stdout ou similaire):
Un entier y
en notation décimale. Le produit x * y
en représentation décimale ne doit contenir que les chiffres 0 et 1. Il doit s'agir du nombre minimal tel que supérieur à 0.
Remarque: la sortie n'est pas limitée - si le minimum y
est d'environ 10 ^ 100, votre programme doit sortir tous ses 100 chiffres (je ne sais pas s'il existe une limite raisonnable, comme 2 ^ 64, sur y
- ne l'a pas résolue ).
Votre programme devrait s'achever dans un délai raisonnable (1 seconde? 1 heure? - quelque chose comme ça) pour tous les participants x
.
Prime:
Si votre programme ne limite pas la taille de l'entrée (à l'exception de la RAM) et a une complexité polynomiale, multipliez le nombre d'octets de votre programme 0.8
et arrondissez-le.
Exemple: entrée 2
; sortie 5
, car 2 * 5 = 10
Exemple: entrée 21
; sortie 481
, car 21 * 481 = 10101
Avertissement: je ne suis pas responsable de la question sur le site Code Review. En cas de divergence, seule la description ci-dessus doit être considérée comme une spécification appropriée.
Réponses:
Pyth, 9 octets
Manifestation
Pour chaque multiple, convertissez-le en chaîne, soustrayez les chiffres
10
entrants (à l'aide de l'entier pratique de Pyth dans str dans ce cas), puis annulez logiquement le résultat en mettant fin à la recherche uniquement lorsque le multiple correct est trouvé.Bonus solution, 10 octets:
Cette solution vérifie réellement si la représentation sous forme de chaîne du nombre peut être traitée comme un nombre binaire (
i ... 2
) et se termine lorsqu'une erreur n'est pas renvoyée lors de cette tentative.la source
Python 2, solution efficace, 99
Merci Sp3000 pour quelques conseils de golf.
I challenge everybody else to post (in their own answers) how long it takes to get the result for input
72
or99
:) If those are really fast, try something like79992
next (still <1 sec here).Explanation:
I thought this wasn't necessary (since the code is fairly readable), but I got a request, so here it goes:
The first idea is that a binary-looking number is a sum of 1 or more different powers of 10. Therefore, we can try to add various powers of 10 in different ways until we get remainder 0.
If we do that naively, it's the same as generating all binary-looking numbers and testing them. But a lot of remainders will be the same. A better way is to record only the smallest number that gave a certain remainder, and successively add greater powers of 10 to numbers we recorded. That's what the program does.
d
is a dictionary/map where keys are remainders and values are binary-looking numbers with that remainder. The initialn:0
is a special case: it's supposed to be0:0
so we can start adding powers to it, but the algorithm stops when finding key 0, so I usedn
instead, which is guaranteed to have the same effect and not interfere with the other values.Ensuite, nous commençons à ajouter des puissances de 10 (stockées dans
k
) à tous les numéros existants et à enregistrer les restes. Nous ajoutonsk
au reste:(x+k)%n
et au nombre:,d[x]+k
et ne l’enregistrons que s’il s’agit d’un nouveau reste:,d.setdefault(…)
puis passez à la puissance suivante:k*=10
et recommencez jusqu’à ce que nous obtenions la clé 0:while min(d)
A la fin,
d[0]
donne le nombre binaire qui a le reste 0 modn
, nous le divisons doncn
pour obtenir la solution.Remarque: le programme peut être rendu plus efficace en évitant les grands nombres (enregistrement des exposants plutôt que de puissances de 10, et calcul des restes de puissances à partir des valeurs précédentes), mais c'est du code golf, alors ...
En fait, ici, j'ai écrit une version plus rapide:
la source
Python 2, 47 bytes
Tracks the input number
n
and the current multiplea
. Whena
looks like binary, output the ratioa/n
. To check that a number is made of0
's and1
's, we compare the maximum char in its string representation to'1'
.Uses
str(a)
instead of`a`
to avoid longs ending inL
. Unfortunately,'L'
is bigger than'1'
.la source
Perl, 27 bytes
Counting the shebang as one, input is taken from stdin.
Sample Usage
Perl, 25 bytes
A two byte improvement by @skmrx.
Rather than checking against a regex, this instead attempts to evaluate the product as a binary literal. Upon failure, it moves on to the next. Typically the
oct
function would be used for this purpose, but it silently trims invalid digits, which isn't useful in this challenge.Perl, 40 bytes
A far more efficient solution. We iterate over binary representations, interpret them as base 10, and then check for divisibility. Runtimes for all values under 100 are negligible.
Sample Usage
la source
eval"0b".$_*++$\||redo}{
use bigint
to support the large numbers that OP has mandated to be supported :(oct'0b'.++$\*$_
, but it silently trims invalid digits. I didn't think to useeval
instead.Javascript, 43 bytes
This ended up way shorter than I thought. It basically increments
y
up 1 untily * (input number) = (binary-looking number)
. Obviously quite inefficient.Javascript (more efficient solution), 53 bytes
This one increments
y
in binary untily / (input number) = (number without a remainder)
. Then it outputs(number without a remainder)
.Javascript (even more efficient solution), 76 bytes
This one combines both of the previous methods described above. It checks increments
y
until eithery * (input number) = (binary-looking number)
(meaning that the output isy
) ORy / (input number) = (number without a remainder)
(meaning that the output is(number without a remainder)
).la source
Haskell,
7270646058 bytesEdit: @Jan Dvorak helped me saving 4 bytes.
Edit: @BlackCap saved 2 bytes by switching to
do
notation. Thanks!la source
main=print.f=<<readLn
main=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
main=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0
Python 2,
67656360 bytesThanks to Status for 2 bytes and Shebang for 5 bytes!
la source
b=1
any(c in`a*b`for c in'23456789')
not c in`a*b`for c in'10'
work?set('a*b')&set('23456789')
.`
produces anL
for longs and'L'>'1'
.JavaScript (ES6) 222
250Using arbitrary precision math (operating on strings of decimal digits)
This can be golfed a little more(done), but I like the fact that it is not limited to JS standard numbers (17 decimal digits of precision) and that it is fast.Test running the snippet below in an EcmaScript 6 compliant browser. Time is acceptable up to 9998 - don't try 9999 and be patient with 999.
More readable
This is the first version, with modulus and long division as separated functions.
la source
Perl, 45 bytes
la source
Pyth, 10 bytes
Run the code.
A port of my Python answer, taking from Maltysen the use of
f
to find the first positive number that meets a condition.la source
PHP, 50 bytes
Some test cases
la source
CJam,
191716 bytesTry it online
Brute force solution, trying values sequentially until one meeting the condition is found.
The latest version saves 2 bytes thanks to using
As
instead of"01"
to build a string containing0
and1
, as suggested by @aditsu. The full proposed solution in the comment saves another byte, but it looks fairly different from mine, so I didn't want to post it under my name.And 1 more byte saved by @Dennis.
Explanation:
la source
li0{1$+_sAs-}g\/
As
to build the string, since it's a very local change, which in hindsight (which is always much easier...) I should have thought of.li:V!{)_V*sAs-}g
Also,0{)_easi*sAs-}g
(15 bytes) works with the Java interpreter and command-line arguments.Python
32,10176 Bytes-25 bytes thanks to @aditsu
almost as efficient as @aditsu's solution
Instead of trying to loop through the multiples in increasing order, I'm trying to loop through the products, which I'm generating in 'binary' form.
la source
n=input()
),while b%n:
(initializeb
to 1), no indentationbin(m)[2:]
should be shorter than the format string. Double assignment onb=m=1
should save a few as well.Java, 213 bytes
Uses
BigInteger
s and as such has (for all reasonable intents and purposes) unbounded input size. Not sure about the complexity though, that depends on the growth rate of our function here.Thanks to geobits and ypnypn for saving a handful of bytes.
la source
static
modifier to the method.b.ONE
and!(b.multiply(c)+"")
(instead oftoString()
).C, 3675 bytes
So long for Code Golf...
Run with no command line parameters - it gets
n
fromstdin
and outputs the result tostdout
. Run with a file name - it writes the results forn = 1...10000
into that file, and measures time.Performance for 1...10000: 140 ms
This code uses the algorithm proposed by aditsu, implemented in C for speed. I made no effort to golf it, so the code would be easier to read.
I implemented it first in C++ using
std::map
to record the results of the search, and it was rather slow. However, the keys of themap
are consecutive integers (I call themmod
s, because they represent numbers modulon
), so it's natural to use an array - so I rewrote it in C.An additional optimization concerns the values of the mapping - in order to avoid storing a big integer for each
mod
, I store only the largest power of 10 there - it's just enough information to go to the previousmod
. So the array is really a search tree/graph. When the search arrives tomod = 0
, tracing the nodes of the tree back to the root gives the powers of 10 in descending order.Since search usually stops rather quickly, with only a small fraction of nodes visited, I need a list of active nodes. It's implemented as an array
mod_list
with lengthmod_list_length
.Some runtime statistics (on a machine with 16 GB RAM, which seems to be important for large
n
, because the program allocates5n
bytes of memory):99999999
- 2 seconds999999999
- 27 seconds (the result is111111111222222222333333333444444444555555555666666666777777777888888889
- probably the largest result possible for 32-bit integers)2147483647
- 26 seconds (the result is4661316525084584315813
)1999999998
- 52 seconds (probably the longest run time possible for 32-bit integers)la source
C++11, many bytes, very fast, wow (1.5 s on 1999999998, 0.2 s on 1…10000)
(Golfed Python version below.)
We start with a concept somewhat similar to aditsu’s solution, where we inductively build up a collection of modular remainders reachable in n steps. But instead of waiting until we find remainder 0, we check for two found remainders a and b such that a·10^n + b = 0. This meet-in-the-middle approach halves the depth of the search tree, so it’s much faster on large inputs and uses much less memory.
Some benchmarks:
Code:
Python, 280 bytes (8.6 seconds on 1999999998 with PyPy)
la source
Mathematica 115 bytes
la source
Java 156 bytes
Massive thanks to aditsu :)
la source
[]
,y
can belong
too, you forgot thex*y+""
trick in the 2nd program, useisEmpty
instead of checking the length, use;
instead of{}
long
wouldn't make the code shorterlong x=…,y;
y
must start from 1, you can initialize it in the declaration, your class doesn't need to be public, and you can movey++
to thex*y
part (x*y++
)Pyth -
1211 bytesUses filter with numeric arg to get first natural number that fulfills predicate, default is 1 which is what we want. Setwise diff to check if only zeros and ones.
Test Suite.
la source
"01
. Saves one char.R, 45 bytes
Usage:
la source
Java,
198193181 bytesThanks to @aditsu for shaving off 5 bytes AND increasing the range of testable numbers!
Note that some values loop negatively due to how Java parses integers. This could be circumvented by BigInteger, but the bonus was simply less valuable.
I know that I'm not going to win, but I hope this inspires other, shorter, answers.
Ungofled:
la source
Long
is shorter thanInteger
:)C,
107101 bytes (10599 bytes for 32-bits)There is a distinct lack of answers in C on code golf. Indeed, C is not the best choice for writing the smallest possible program, but it's not that bad:
You can do without the #includes, but then all the function definitions will be implicit. The main drawback is that this causes the assumption that all functions return ints. This is a problem on 64-bit machines for functions that actually return a pointer. If you are on a 32-bit machine, 2 bytes can be shaved off the above solution:
Somewhat more readable version:
la source
C# time near 5 seconds (1 to 10000)
As requested, here is a golfed C# program answering the original challenge. Input as command line argument, output to console.
Then, as for the bounty: the bounty should go to aditsu, as I think his algorithm cannot be beaten in terms of perfomance. But anatolyg self-answer is amazing too.
Here is my fast implementation in C#. I suppose that in C++ it could be faster (maybe 2x). Compiled and tested with Visual Studio 2010, .NET framework 4, 64 bits, redirecting output to nul. Time : 00:00:05.2604315
la source
Keys.Reverse
? Is the order important? If it's just to avoid concurrency issues,ToList
is shorter.C with GMP (621 bytes, fast)
I've tried to be fast and short, but favoured fast. This implementation uses a slightly improved version of the number-theoretic speedup I mentioned in a comment on aditsu's answer.
Save as
pseudobinary.c
and compile withgcc pseudobinary.c -lgmp -o pseudobinary
. Note that this allocates so much memory for large inputs that you will need to compile it for a 64-bit platform.Loop version for timing (751 bytes)
Ungolfed loop version
la source
C + GMP, 669
This is really fast for smallish numbers; it starts to choke when the result has more than 64 digits.
Version that loops to 10000 (671 bytes):
Here are some commands for testing my code as well as my competitors', and the results on my laptop:
la source
T-SQL,
164156155154159 bytes(-1 byte. Thanks Jonathan!)
(-1 more because why do I have trailing spaces on lines? SMH)
(+5 realized my golfing broke things)
I don't know why I keep coming back to these questions where I'm supposed to convert to Binary... T-SQL doesn't know how to do that right.
In any case, here's a SQLFiddle.
Un-golfed:
Most of this stuff is required to write a function in T-SQL, as far as I'm aware.
Create a blank string that we're going to store as our binary number.
Save the input value for use at the end. It seems like there should be a way to use the original input even if we change the value, but I can't find one.
So we take our original input, MOD it with 2 to find the remainder, and that's going to be our next smallest digit. For example, 5%2 = 1
Then we take our number, and divide it in half. Because it's an
int
type, it rounds it down to the nearest whole number, so 5/2 = 2. END We then loop through this until the value is 0. So we end up with 5%2 = 1 5/2 = 2 2%2 = 0 2/2 = 1 1%2 = 1 1/2 = 0 which gives us our binary string value of 101.We take our binary string and convert it back to an
int
again.We return our binary string
int
divided by our original value, per the origin of the question.la source
@>0 SELECT
not omittable?Ruby, 46 bytes
I should really eliminate the while loop with an alternative loop.
Edit: Thanks @manatwork for shaving off 1 byte!
Edit2: Thanks @histocraft for the insane 9 bytes!
Edit: Thanks @manatwork again for shaving off 7 bytes!
la source
z!=z[/[01]+/]
is shorter.z[/[^01]/]
is even more shorter.z="#{n.to_i*k+=1}"while z[/[^01]/]
Scala, 114 Bytes
Readable version
la source
gawk4 brute force, 28+2 = 30 bytes
Needs to be called with the
-M
option for using big numbers. Of course this is ridiculously slow, using big numbers slows it down even more, but theoretically the input is not limited, and RAM usage is negligible.Usage example ( if you got time to waste
;)
)gawk4 optimized, 69+2 = 71 bytes
Well, this ended up being a clone of aditsu's answer. After looking at this question I was still figuring out how to code the subset-sum part, when I couldn't resist looking at the other answers here.
In awk array elements have the (strange ?) behaviour that if you compare a non-existing element to something it is somehow initialized as empty before being compared (I'll admit that I'm not quite sure about what is happening there). So after checking
!a[0]
thefor(i in a)
loop starts even without initializinga[$0]
to0
as aditsu did.Of course the
-M
option has to be used for this too.Though it is rather fast it is still remarkably slower than Python. For
79992
this takes around 14 seconds on my 2GHz Core2Duo. And I wouldn't say it works for inputs up to 2^31, because in the worst case it has to build an array of big numbers (gawk4 uses GMP for this), which has the size of the input number. As a 'bonus' large arrays are very very slow in awk...la source
Dyalog APL, 25
This defines a proper program "P" (not just an unnamed function):
2∘
begin with 2 as left argument0::
if there is any error...⍵∇⍨1+⍺
call itself with an incremented left argument⍺×⍵
multiply left and right arguments⍕
make into string⍎¨
make each character into a number~
attempt logical NOT (if it fails, go to error-handling above, else...)⍺⊣
return the current left argument.la source