Zahlen in Binär umwandeln… aber Sie dürfen auch Zweien verwenden

20

Schreiben Sie auf der Grundlage der in diesem Numberphile-Video erwähnten "binären, aber mit Zweien" -Notation eine Funktion, die eine einzelne Zahl als Eingabe verwendet und alle Variationen dieser Zahl in einem "binären" System ausgibt , in dem Zweien zulässig sind.

Regeln

  • Code darf nur eine Funktion / Methode sein, kein vollständiges Programm
  • Die Eingabe ist eine Ganzzahl, die als einziger Parameter an die Funktion übergeben wird
  • Bei der Ausgabe handelt es sich um alle gültigen Variationen der eingegebenen Nummer, die in "binär, aber mit Zweier-Notation" konvertiert wurden
  • Die Ausgabe ist der Rückgabewert der Funktion, kann jedoch in jedem beliebigen Format erfolgen, sofern dies offensichtlich ist (z. B. 3 Ints, 3 Strings, durch Kommas / Leerzeichen getrennte Strings, Array von Ints usw.). Die Reihenfolge ist unwichtig
  • In dem unwahrscheinlichen Fall, dass eine Sprache eine eingebaute Funktion enthält, um das Ergebnis zu erzielen, ist dies nicht zulässig
  • Kürzester Code in Bytes ist der Gewinner

Erklärung der Ausgabe

Wenn Sie beispielsweise die Zahl übergeben haben 9, können Sie sie in binär als konvertieren. 1001Wenn Sie jedoch 2s an jeder Position zulassen , können Sie sie auch als 201(dh 2*4 + 0*2 + 1*1) oder 121(dh 1*4 + 2*2 + 1*1) schreiben , wie in der folgenden Tabelle gezeigt:

+----+----+----+----+
| 8s | 4s | 2s | 1s |
+----+----+----+----+
|  1 |  0 |  0 |  1 |
|  0 |  2 |  0 |  1 |
|  0 |  1 |  2 |  1 |
+----+----+----+----+

Wenn also bestanden 9, müsste Ihre Funktion die drei Zahlen 1001, 201und zurückgeben 121.

Format und Ordnung ist irrelevant, solange es offensichtlich ist (dh [121,201,1001], "0201 0121 1001", ("1001","121","201")sind gültige Ergebnisse , wenn eine Eingabe gegeben 9).

Beispiele

  • 2 => 10, 2
  • 9 => 1001, 201, 121
  • 10 => 1010, 210, 202, 1002, 122
  • 23 => 2111, 10111
  • 37 => 100101, 20101, 100021, 20021, 12101, 12021, 11221
Alconja
quelle
3
Es gibt keine zwei.
MikeTheLiar
1
Zwei? In binär? Ist das Quantencomputing?
Matthew Roh

Antworten:

10

GolfScript (25 Bytes) / CJam ( 19 - 17 Bytes)

GolfScript:

{:^.*,{3base}%{2base^=},}

Dadurch wird eine anonyme Funktion erstellt (siehe Metadiskussion zur Zulässigkeit anonymer Funktionen ).

Online-Demo

Eine direkte Übersetzung in CJam ist (danke an Martin Büttner für das Rasieren einiger Charaktere)

{:X_*,3fb{2bX=},}

Präparation

{             # Function boilerplate
  :^          # Store parameter as variable ^
  .*          # Square parameter - see detailed explanation below
  ,{3base}%   # Produce an array of 0 to ^*^-1 in ternary
  {2base^=},  # Filter to those which evaluate to ^ in binary
}

Der Grund für die Quadrierungsoperation ist, dass wir bis zum größtmöglichen Wert iterieren müssen, dessen ternäre Darstellung, in Binärform interpretiert, gleich ist ^. Da 2 = 10ist die "normale" Binärdarstellung ^derjenige, auf den es ankommt. Wenn wir das in ternäre umwandeln, stellen wir fest, dass die "schlimmsten" Fälle Potenzen von 2 sind. Ein optimaler Ansatz wäre, das Argument auf die Potenz von zu setzen ln 3/ln 2 ~= 1.585, aber die Quadratur ist viel kürzer.

Peter Taylor
quelle
Ich wette, eine CJam-Übersetzung wird viel kleiner sein.
Optimierer
1
@Optimizer weitermachen ;-)
John Dvorak
GolfScript? Mann, ich bin so ein Noob
Pythonian29033
8

Python 2 (59 Bytes)

S=lambda n,B="":[B][n:]or~n%2*S(n/2-1,"2"+B)+S(n/2,`n&1`+B)

(Vielen Dank an @grc, @xnor und @PeterTaylor für die Hilfe im Chat)

Einfache Rekursion, Aufruf mit S(23)oder ähnlich.

Erläuterung

Die allgemeine Idee ist, dass, wenn ndie binäre Erweiterung mit a endet 1, jede pseudobinäre Erweiterung ("binär, aber mit zwei") auch mit a enden muss 1. Andernfalls könnte es mit 0oder enden 2.

Daher schauen wir uns das letzte Stück an n, teilen es auf und verzweigen es entsprechend.

Präparation

S=lambda n,B="":           # Lambda expression
[B][n:]or                  # Short circuit, return [B] if n==0 else what follows
~n%2*                      # Keep next list result if n is even else turn into []
S(n/2-1,"2"+B)             # Add a "2" to B, recurse
+
S(n/2,`n&1`+B)             # Add "0" or "1" to B depending on n's last bit, recurse

Variablen:

  • n: Die Zahl, deren pseudobinäre Erweiterungen wir finden wollen
  • B: Eine Pseudo-Binärzeichenfolge, die von rechts nach links erstellt wird
Sp3000
quelle
5

Bash + Coreutils, 77

f()(seq `dc -e2o$1p`|sed '/[3-9]/d;s/.*/&n9P2i&pAi/'|dc|grep -Po ".*(?= $1)")

(Das ist ein TABZeichen im grep-Ausdruck.)

Das verbiegt diese Regel ein bisschen:

"In dem unwahrscheinlichen Fall, dass eine Sprache eine eingebaute Funktion enthält, um das Ergebnis zu erzielen, ist dies nicht zulässig."

Es stellt sich heraus , dass dchat das Gegenteil von dem, was wir in gebaut brauchen. Zum Beispiel , wenn wir die Eingangsbasis 2 und Eingang eine binäre Zahl mit Zweien gesetzt, es wird es richtig analysieren. (In ähnlicher Weise werden AF als dezimale "Ziffern" 10-15 analysiert, wenn der Eingabemodus "Basis 10" ist.)

seqErstellt eine Liste aller Dezimalzahlen bis zur binären Standarddarstellung von n, die als Dezimalzahl analysiert werden. Dann werden alle Zahlen, die etwas anderes als {0,1,2} enthalten, herausgefiltert. Dann werden dcdie verbleibenden Zahlen als binär analysiert, um zu sehen, welche zurück zu n ausgewertet werden.

Bash-Funktionen können nur skalare Ganzzahlen von 0 bis 255 "zurückgeben". Daher erlaube ich mir, die Liste als "Rückkehr" zu STDOUT auszudrucken. Dies ist typisch für Shell-Skripte.

Ausgabe:

$ f 2
2   
10  
$ f 9
121 
201 
1001    
$
Digitales Trauma
quelle
4

Haskell, 82

t n=[dropWhile(==0)s|s<-mapM(\_->[0..2])[0..n],n==sum[2^(n-i)*v|(i,v)<-zip[0..]s]]

Dies ist nur eine Brute-Force-Lösung. es ist sehr ineffizient, da erwartet wird, dass es 3 ^ n Möglichkeiten durchbricht.

stolzer haskeller
quelle
3

Jelly , 10 Bytes, Sprachnachstellung

ṗ@3Ḷ¤Ḅ=¥Ðf

Probieren Sie es online!

Eine Bruteforce-Lösung bis zu einer Anzahl von Hyperbits, die der Eingabe entsprechen (dieses Format wird als "hyperbinary" bezeichnet). Als solches ist es unglaublich ineffizient und läuft in O (3 n ).

Erläuterung

ṗ@3Ḷ¤Ḅ=¥Ðf
ṗ@            Construct all lists with the given length, and elements taken from
  3Ḷ¤         the list [0,1,2]
        Ðf    then take only those elements which
     Ḅ=¥      when interpreted as binary, equal {the original number}

quelle
2

PHP, 138 Bytes

function p($v,$i=0,$r=""){global$a;if($v==0)$a[]=$r?:0;elseif($v>0)for(;$l<3;)p($v-2**$i*$l,$i+1,+$l++.$r);}p($argv[1]);echo join(",",$a);

Nervenzusammenbruch

function p($v,$i=0,$r=""){
    global$a;
    if($v==0)$a[]=$r?:0;  # fill result array
    elseif($v>0) # make permutations
        for(;$l<3;)
            p($v-2**$i*$l,$i+1,+$l++.$r); #recursive
}
p($argv[1]);
echo join(",",$a); # Output
Jörg Hülsermann
quelle
1

C ++, 159 Bytes

void c(int x,string r){int i,t=0,s=r.size();if(s<8){if(r[0]>48){for(i=0;i<s;i++)t+=(r[s-i-1]-48)*1<<i;if(t==x)cout<<r<<" ";}for(char n=48;n<51;n++)c(x,r+n);}}

Teste es hier

Johan du Toit
quelle
1

k, 21 Bytes

Verwendet die gleiche Methode wie die Golfscript-Antwort von Peter Taylor

{X@&x=2/:'X:3\:'!x*x}

Beispiele:

k) {X@&x=2/:'X:3\:'!x*x}9
(1 2 1;2 0 1;1 0 0 1)
k) {X@&x=2/:'X:3\:'!x*x}10
(1 2 2;2 0 2;2 1 0;1 0 0 2;1 0 1 0)
Skeevey
quelle