Konvertieren Sie 1 in eine positive Ganzzahl, indem Sie nur die Operationen * 3 und / 2 verwenden

11

Jede positive ganze Zahl kann erhalten werden, indem mit 1 begonnen und eine Folge von Operationen angewendet wird , von denen jede entweder "mit 3 multiplizieren" oder "durch 2 dividieren und den Rest verwerfen" ist .

Beispiele (Schreiben von f für * 3 und g für / 2):

4 = 1 *3 *3 /2 = 1 ffg
6 = 1 ffggf = 1 fffgg
21 = 1 fffgfgfgggf

Schreiben Sie ein Programm mit folgendem Verhalten:

Eingabe : jede positive ganze Zahl, über stdin oder fest codiert. (Wenn fest codiert, wird die Eingabezahl von der Programmlänge ausgeschlossen.)
Ausgabe : Eine Zeichenfolge von fs und gs, so dass <input> = 1 <string>(wie in den Beispielen). Eine solche Zeichenfolge in umgekehrter Reihenfolge ist ebenfalls akzeptabel. NB: Die Ausgabe enthält nur fs und gs oder ist leer.

Der Gewinner ist der Eintrag mit den wenigsten Bytes an Programm plus Ausgabe, wenn 41 die Eingabe ist.

res
quelle
1
Woher weißt du, dass das wahr ist?
Marinus
@marinus dies wird angenommen, um wahr zu sein (aber noch nicht bewiesen). auf der Suche nach einem Beweis.
Fabinout
@marinus, du kannst beweisen, dass es durch Abstieg (oder gleichwertig durch starke Induktion) möglich ist. Fallaufteilung auf x mod 3: wenn x=3yy konstruieren und dann anwenden f; wenn x=3y+1konstruieren 2y+1und anwenden fdann g; wenn x=3y+2es dann kompliziert wird, aber im Wesentlichen rekursiv ist.
Peter Taylor
Muss die Ausgabe in einer separaten Notiz in der Reihenfolge der Anwendung erfolgen oder wäre auch die Reihenfolge der Komposition akzeptabel?
Peter Taylor
@ PeterTaylor So oder so ist OK.
Res

Antworten:

3

GolfScript, Punktzahl 64 (43-2 + 23)

0{)1.$2base:s{{3*}{2/}if}/41=!}do;s{103^}%+

(41 ist fest codiert, daher -2 Zeichen für die Partitur). Die Ausgabe ist

fffgffggffggffgggffgggg

Das sind 23 Zeichen (ohne Zeilenumbruch). Durch die Konstruktion garantiert der Code, dass er immer (eine) der kürzesten Darstellungen zurückgibt.

Howard
quelle
Zitat von Benutzer Darren Stone in einem Änderungsvorschlag zu diesem Beitrag: "Ich kann hier keinen Kommentar hinterlassen, daher werde ich eine Bearbeitung hinterlassen. Diese Ausgabe enthält weder die ersten beiden Zeichen" 1 "noch die in der Punktzahl wiedergegebenen. Sollte eine sein einfache Lösung und immer noch eine unglaublich kurze Lösung. Prost! " (Ich lehnte ab, dachte aber, ich sollte die Nachricht tragen)
Türknauf
@Doorknob Die Herausforderung besagt, dass das "1 "nicht in die Ausgabe aufgenommen werden soll.
Howard
3

Wir werden schmutzig, Freunde!

JAVA 210 207 199 Zeichen

public class C{public static void main(String[] a){int i=41;String s="";while(i>1){if(i%3<1){s+="f";i/=3;}else if(i%3<2){s+="g";i+=i+1;}else{s+="g";i+=i+(Math.random()+0.5);}}System.out.println(s);}}

Nicht Golf:

public class C {

    public static void main(String[] a) {

        int i = 41;
        String s = "";
        while (i > 1) {
            if (i % 3 == 0) {
                s += "f";
                i /= 3;
            } else {
                if (i % 3 == 1) {
                    s += "g";
                    i += i + 1;
                } else {
                    s += "g";
                    i += i + (Math.random() + 0.5);
                }
            }
        }
        System.out.println(s);
    }
}

Ausgabe: Abhängig vom Glauben der alten Götter war die kürzeste, die ich hatte, 30. Beachten Sie, dass die Ausgabe von rechts gelesen werden muss.

234

1 ggfgfgfgfggfggfgffgfggggfgffgfggfgfggggfgffgfggfgfggfgfggfgfgggggfffgfggfgfggfgfgggffgggggfffgfggggfgffgfggfgfggfgfggfgfggfgfggfgfggfgfggggfgffgfggfgfggfgfggfgfggfgfggfgfggggggggggggfgfgfggggfgfgfggfffgfgfggffgfgfggfgfggggffgfgfffff

108

1 gggffgfgfggggggfggggfgffggggfgfgfgfgfgffgggfgggggfggfffggfgfffffgggffggfgfgggffggfgfgggffggggggfgfgffgfgfff

bearbeiten 45

1 ggfgfgfgfgggfggfffgfggfgfgggggggffgffgfgfff

Punkte: 318 199 + 30 = 229

edit1 (2 * i + 1)% 3 == 0 -> (2 * i)% 3 == 1

Nota Bene, wenn Sie beim Golfen Java 6 und nicht Java 7 verwenden, können Sie verwenden

public class NoMain {
    static {
        //some code
        System.exit(1);
    }
}

Struktur mit 39 Zeichen anstelle einer Standardstruktur mit 53 Zeichen.

Fabinout
quelle
(2*i+1)%3==0ist gleichbedeutend miti%3==1
Howard
Ja ist es. danke
Fabinout
if(X){A}else{if(Y){B}else{C}}ist länger als if(X){A}else if(Y){B}else{C}. Sie können Ihre ==Bedingungen auch durch kürzere <Bedingungen ersetzen .
Peter Taylor
@ PeterTaylor stimmt, meine Lösung ist immer noch hässlich. Ich weiß nicht, ob der zufällige Teil den Code kürzer macht, aber es macht die Ausgabe sicher schlechter.
Fabinout
Ihre f / g-Zeichenfolgen beginnen mit 'g' (was für '/ 2' stehen soll), sodass sie 1 in 0 statt in 41 konvertieren. Das Ändern der fs in gs und umgekehrt scheint ebenfalls nicht zu sein geben 41.
res
3

Python, Punktzahl 124 (90-2 + ​​36)

x=41;m=f=g=0
while(3**f!=x)*(m!=x):
 f+=1;m=3**f;g=0
 while m>x:m/=2;g+=1
print'f'*f+'g'*g

90 Zeichen Code (Zeilenumbrüche jeweils 1) - 2 für fest codierte Eingabezahlen + 36 Zeichen Ausgabe

Ausgabe:

ffffffffffffffffgggggggggggggggggggg
Darren Stone
quelle
1
Wenn Sie dies tun m=f=0, können Sie die äußere Schleife erstellen while(n!=x)*(m!=x)und die Unterbrechungen entfernen. Bringt es auf 95 Zeichen Code.
Daniel Lubarov
@ Daniel: Sie, Sir, sind ein Gentleman und ein Gelehrter. Vielen Dank! Ihre Einreichung ist immer noch sicher 10 Zeichen vor mir. :)
Darren Stone
1
Sie können ein wenig weiter sparen, wenn Sie alle ndurch ersetzen 3**f.
Howard
1
Bei Eingabe = 1 generiert Ihr Programm einen Fehler ("Name 'g' ist nicht definiert", da die äußere while-Schleife nicht eingegeben wird).
Res
1
Sie könnten ein anderes Zeichen durch Schreiben ausschneiden print'f'*f+'g'*g, was eine Punktzahl von 90-2 + ​​36 = 124 ergeben würde.
Res
3

Python, Punktzahl 121 (87 - 2 + 36)

t=bin(41)
l,n,f=len(t),1,0
while bin(n)[:l]!=t:f+=1;n*=3
print(len(bin(n))-l)*'g'+f*'f'
Daniel Lubarov
quelle
@Darren, ich war mir nicht sicher, wie ich die Ausgabebeschreibung interpretieren sollte, aber du hast wahrscheinlich recht. Ich habe die '1' hinzugefügt. Vielen Dank!
Daniel Lubarov
1
Sie können die '1' (wieder!) Löschen. Ihre ursprüngliche Interpretation der Ausgabebeschreibung war korrekt. Genießen Sie wieder die Python-Führung! :-)
Darren Stone
1
Wenn Sie Ihre 2., 3. und 4. Zeile in der Druckanweisung kombinieren l,n,f=len(t),1,0und '1',aus der Druckanweisung entfernen , beträgt Ihre Punktzahl 87-2 + 36 = 121.
Res
Danke Jungs - ich habe das fallen lassen 1,. l,n,f=len(t),1,0gibt die gleiche Anzahl von Zeichen, richtig? (Für jede Variable wird eine =und eine neue Zeile durch zwei ,s ersetzt.)
Daniel Lubarov
Wenn jede neue Zeile aus einem Zeichen besteht (z. B. LF im UNIX-Stil), haben die einzeilige und die dreizeilige Version dieselbe Länge. Wenn jede neue Zeile aus zwei Zeichen besteht (z. B. CR + LF im MS Windows-Stil), ist die einzeilige Version zwei Zeichen kürzer als die dreizeilige Version. Die Punktzahl von 121 setzt einzeilige Zeilenumbrüche voraus.
Res
1

Perl, Punktzahl 89 (63 - 2 + 28)

$_=41;$_=${$g=$_%3||$_==21?g:f}?$_*2+$_%3%2:$_/3while$_>print$g

Vermutung: Wenn der in meiner ursprünglichen Lösung unten beschriebene naive Ansatz jemals einen Zyklus erreicht, wird dieser Zyklus [21, 7, 15, 5, 10, 21, ...] sein . Da es keine Gegenbeispiele für 1 ≤ n ≤ 10 6 gibt , scheint dies wahrscheinlich zu stimmen. Um dies zu beweisen, würde es genügen zu zeigen, dass dies der einzige Zyklus ist, derexistieren kann , was ich zu einem späteren Zeitpunkt tun kann oder nicht.

Die obige Lösung vermeidet den Zyklus sofort, anstatt (falsch) zu raten und ihn beim zweiten Mal zu vermeiden.

Ausgabe (28 Bytes):

ggfgfgfgfggfggfgfgfggfgfgfff

Perl, Punktzahl 100 (69 - 2 + 33)

$_=41;1while$_>print$s{$_=$$g?$_*2+$_%3%2:$_/3}=$g=$_%3||$s{$_/3}?g:f

Verwenden eines Guess-and-Check-Ansatzes. Die Zeichenfolge wird mithilfe inverser Operationen erstellt (Konvertieren des Werts in 1 statt umgekehrt), und die Zeichenfolge wird entsprechend gespiegelt, was in der Problemspezifikation zulässig ist.

Immer wenn ein Nicht-Vielfaches von drei angetroffen wird, wird es mit zwei multipliziert und eins addiert, wenn das Ergebnis dann ein Vielfaches von drei wäre. Wenn ein Vielfaches von drei angetroffen wird, wird es durch drei geteilt ... es sei denn, dieser Wert wurde zuvor angetroffen, was auf einen Zyklus hinweist, also Vermutung und Überprüfung.

Ausgabe (33 Bytes):

ggfgfgfgfggfggfgffgfgggfggfgfgfff
primo
quelle
1

J, Punktzahl 103 (82-2 + 23)

* Hinweis: Ich habe meine Verben benannt fund gdarf nicht mit Ausgabezeichenfolgen fund verwechselt werden g.

Fest codiert:

f=:3 :'s=.1 for_a.y do.s=.((<.&-:)`(*&3)@.a)s end.'
'gf'{~#:(>:^:(41&~:@f@#:)^:_)1

Allgemeine Funktionen:

f=:3 :'s=.1 for_a.y do.s=.((<.&-:)`(*&3)@.a)s end.'
g=:3 :'''gf''{~#:(>:^:(y&~:@f@#:)^:_)1'

Die Bearbeitung von Binärzahlblöcken wurde abgeschafft, was die wichtigste Änderung in Bezug auf die Komprimierung war g. Variablen umbenannt und zum Teufel einige Leerzeichen entfernt, aber funktionell ist immer noch alles gleich. (Verbrauch: g 41)

J, Punktzahl 197 (174 + 23)

f =: 3 : 0
acc =. 1
for_a. y do. acc =. ((*&3)`(<.&-:)@.a) acc end.
)

g =: 3 : 0
f2 =: f"1 f.
l =. 0$0
i =. 1
while. 0=$(l=.(#~(y&=@:f2))#:i.2^i) do. i=.>:i end.
'fg'{~{.l
)

Ausgabe: ffffffffggggggggfgffggg

fkonvertiert eine Liste von Booleschen Werten in Zahlen, wobei 0s als *3und 1s als /2(und floor) verwendet werden. #:i.2^iErstellt ein Array mit Rang 2, das alle booleschen Arrays mit Rang 1 enthält i.

rationalis
quelle