Generieren Sie die Stöhr-Sequenz


12

Ich lerne Ruby und habe meinen ersten nichttrivialen Code geschrieben, um dieses Problem zu lösen.

Die Herausforderung ist es, die erste zu erzeugen , n Elemente der Stöhr Sequenz , S , die wie folgt definiert ist:

S [0] = 1

S [n] ist die kleinste Zahl, die nicht als Summe zweier unterschiedlicher vorheriger Elemente in der Sequenz ausgedrückt werden kann.

Die Folge beginnt also mit 1, 2, 4, 7 und 10. Das nächste Element ist 13, da 11 (= 1 + 10) und 12 (= 2 + 10) Summen vorheriger Elemente sind, 13 jedoch nicht.

Ich suche den kürzesten Code. Mein eigenes in Ruby ist 108 Zeichen lang, aber vielleicht werde ich warten, bis andere es herausfinden, bevor ich es poste?


Ich mag die Antworten so weit. Jetzt ist es vielleicht zu spät, um noch einmal die Anforderungen zu ändern, aber ich hätte wohl erwähnen sollen, dass ich besonders an Lösungen interessiert bin, die die Definition der Sequenz selbst verwenden (dh der Code weiß das letztendlich nicht im Voraus) die Zahlen steigen um 3). Also: moralische Bonuspunkte, wenn Sie das können.
Théophile

Dies ist das Problem mit mathematischen Sequenzen. Wenn Sie das Muster kennen, ist es normalerweise kürzer.

Diese Folge ist arithmetisch ohne Verwendung (?).
User75200

@ user75200 Die Folge ist nicht arithmetisch, wie Sie an den Unterschieden der ersten drei Elemente erkennen können, aber die Teilfolge ab dem dritten Element ist tatsächlich arithmetisch. Es wird in Verbindung mit dem Postage Stamp-Problem verwandt.
Théophile

Antworten:


13

APL, 7

In APL können Sie wählen, ob Sie mit Index 0 oder Index 1 arbeiten möchten. Setzen Sie dazu die globale Variable ⎕IO ← 0

Wenn wir uns für Index 0 entscheiden, haben wir:

+\3⌊1⌈⍳

Erläuterung:

⍳    creates a sequence 0...n   (0 1 2 3 4 5)
1⌈   takes whichever is bigger, number in sequence or 1 (1 1 2 3 4 5)
3⌊   takes whichever is lower, number in sequence or 3 (1 1 2 3 3 3)
+\   partial sums for the sequence (1 2 4 7 10 13)

Probieren Sie es auf tryapl.org


Können Sie nicht mit 1-basiertem Index arbeiten und dann ein 1-zu-n-Array erstellen und ihm einfach eine weitere 1 voranstellen? Wenn das möglich ist, ist es dann kürzer?
Optimierer

Der Code, den ich bekommen habe, war länger. Dies war mein Code für Index 1, 10 Zeichen: + \ 3⌊1, ⍳¯1 + Auch die Index-0-Version funktioniert mit Argument 0, während dies nicht der Fall ist.
Moris Zucca

Ah. ja APL hat sich hier wirklich durchgesetzt ..
Optimizer

9

Haskell - 11 21

Faule unendliche Folge

1:2:[4,7..]

Funktion, die die gerade angegebene Anzahl von Mitgliedern zurückgibt (Seufzer)

flip take$1:2:[4,7..]

Sie müssen eine Eingabe machen und nur die ersten nZahlen ausdrucken .
Optimierer

4
@Optimizer Nun, technisch , Sie haben , um „die ersten zu erzeugen n Elemente der Folge Stöhr“-Sie nicht sagen können , den Rest von ihnen auch nicht erzeugen! Es heißt auch nicht, dass Sie eine Eingabe machen müssen. Der ursprüngliche Code von swish generiert tatsächlich die ersten n Terme für jedes n .
wchargin

1
@WChargin ist nicht neu Wenn der Wortlaut des OP zu wörtlich genommen wird und mehr Output als erforderlich erzeugt wird, gelten beide als Standardlücken.
Optimierer

2
@Optimizer Eigentlich bedeutet Faulheit, dass keine zusätzliche Ausgabe generiert wird, bis Sie danach fragen, und Sie können nach beliebigen Begriffen fragen .
Swish

1
@swish verstehe ich nicht. Was ist hier faul?
Optimierer

7

Python 2, 37 35 Bytes

lambda n:[1,2][:n]+range(4,n*3-4,3)

Ein Muster anwenden ...


1
Sie können die 4in den Bereich aufnehmen:lambda n:[1,2][:n]+range(4,n*3-4,3)
Jakube

Schöner Fund. Bearbeitet auf 35 jetzt.
Logic Knight

6

CJam, 14 Bytes

1l~{_p_3e<+}*;

Teste es hier.

Beginnt bei 1. Dann ist S [n] = S [n-1] + min (S [n-1], 3) .

1l~{_p_3e<+}*;
1              "Push 1.";
 l~            "Read and evaluate input N.";
   {       }*  "Repeat this block N times.":
    _p         "Duplicate the last number and print it.";
      _3e<     "Duplicate it again, and take minimum with 3.";
          +    "Add to last number.";
             ; "Discard final number to prevent output.";

Dies verallgemeinert sich leicht zu h- Stöhr-Sequenzen, wenn wir 3 durch 2 h -1 ersetzen .


6

Brainfuck, 13 Zeichen

+.+.++.[+++.]

Oder 30 Zeichen, wenn wir es auf n Ausgaben beschränken wollen:

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

1
Ich denke, Sie müssen die ersten nElemente drucken , nicht einen unendlichen Strom von ihnen ...
Sp3000

@ Sp3000 Wird die Verwendung von Zeichencodes als numerische Eingabe und Ausgabe allgemein akzeptiert? Kann nicht auf Meta finden. Damit wäre es ziemlich einfach, BF-Code zu korrigieren.
Randomra

Persönlich bin ich mir nicht sicher, was der allgemeine Konsens dafür ist, sorry. Ich hatte auch ein kleines Problem damit.
Sp3000,

Für die ersten n Elemente denke ich, dass ich -> +. <[-> +. <[-> ++. <[-> +++. <]]] (29 Zeichen) tun könnte, aber das ist nicht so elegant . Und ich glaube nicht, dass die Sprache speziell auf die Verwendung von ASCII-Codes für die Eingabe und Ausgabe beschränkt ist.
Jgosar

1
Ihr Code muss die Frage beantworten, auch wenn sie nicht so elegant ist. Ich würde vorschlagen, den Beitrag zu bearbeiten und die Antwort auf zu korrigieren ,->+.<[->+.<[->++.<[->+++.<]]]. (Sie haben am Anfang das eingegebene
Lesekomma

4

Python, 136 Bytes

def f(n):
 if n<1:return[1]
 x=f(n-1);y=set(x)|{a+b for a in x for b in x if a!=b};return x+[min([a for a in range(1,max(y)+2)if{a}-y])]

Direkt aus der Definition. Ich bin mir nicht sicher, wie viel ich Golf spielen kann - es ist sicherlich viel länger als ich erwartet hatte.


3

J, 14 Zeichen

Dies codiert nur die [1,2, 4+3*k (k=0..n-1) ]Sequenz und nimmt die erste N.

   ({.1,2,4+3*i.) 10
1 2 4 7 10 13 16 19 22 25

.

J, 18 Zeichen

Dieser verwendet eine lineare Kombination von [0,1,2,3...], [1,1,0,0...]und [0,1,1,1...]. Sollte kürzer sein, scheint aber nicht Golf zu spielen.

   ((3&*+<&2-2**)@i.) 10
1 2 4 7 10 13 16 19 22 25

3

Vorspiel , 32 20

Edit: ... jetzt mit doppelten Stimmen!

?(1-)
4 +3
2  ^
1 !^

Dies setzt den Python-Interpreter mit voraus NUMERIC_OUTPUT = True. Wie bei der Übermittlung von Brainfuck wird bei dieser Antwort davon ausgegangen, dass die Eingabe in Form eines Codepunkts erfolgt. Dies ist zum Teil , um mehr Aufmerksamkeit für diese Metadiskussion zu bekommen (und zum Teil, weil ich Prelude liebe). Wenn Sie also beispielsweise die ersten 32 Zahlen drucken möchten, müssen Sie in STDIN ein Leerzeichen einfügen. Das bedeutet natürlich, dass es eine Obergrenze für die gültigen Eingaben gibt, aber diese Antwort gewinnt sowieso nicht, daher denke ich, dass dies innerhalb der Einschränkungen von Prelude in Ordnung ist.

Erläuterung

Im Prelude werden alle Zeilen parallel ausgeführt, wobei diese Zeile einen eigenen Stapel hat, der mit einer unendlichen Anzahl von Nullen initialisiert ist. Es gibt nur einen einzelnen Anweisungszeiger (der auf Spalten zeigt). Wenn Sie also eine Schleife für eine Stimme eingeben, werden alle anderen Stimmen mitgeschleift.

Im Folgenden habe ich den Code transponiert, sodass ich Zeilen anstelle von Spalten mit Anmerkungen versehen kann:

?421  Read a character into the first stack. Push 4, 2, 1 onto the other stacks, respectively.
      Generally, the fourth stack will hold the next number to be printed, the third stack the
      one after that, and the second stack the number two steps ahead.
(     Start a loop if the input wasn't 0.
1+ !  Push a 1 onto the first stack. Add the top elements in the second stack. On the first
      iteration this will be 0 and 4, so it does nothing. On all further iterations
      this will increment the last number by 3.
-3^^  Subtract one from the first stack. Push a 3 onto the second stack for the next iteration.
      Copy the last value from the second to the third, and the third to the fourth stack.
)     If the top of the first stack is not 0, jump back to the column after the (.

2

JavaScript (ES6) 92

Als rekursive Funktion basierend auf der Problemdefinition

S=(n,v=1,s=[],r=0)=>[for(a of s)for(b of s)r+=(a-b&&a+b==v)]|r||(s.push(v),--n)?S(n,v+1,s):s

Verwenden Sie das Muster 1,2, 1 + 3 * k: 58

S=(n)=>(i=>{for(t=1;n>r.push(t+=i);i+=(i<3));})(0,r=[])||r

Randnotiz: Finden der h-Stöhr-Folge (Verifizieren der Summe von bis zu hZahlen anstelle von nur 2). Die RFunktion versucht alle möglichen Summen einer bestimmten Anzahl von Listenelementen.

S=(n,h=2,s=[],v=1,R=(t,v,l,i=0,r=t,w)=>{
  for(;r&&l&&v[i];i++)
    w=[...v],r=!R(t-w.splice(i,1),w,l-1)
  return!r;
})=>R(v,s,h)||(s.push(v),--n)?S(n,h,s,v+1):s

Ungolfed ungefähr gleichwertig (und ES5 kompatibel)

function S(n, v, s)
{
  var r=0,a,b
  v = v||1
  s = s||[]
  for(a of s)
    for(b of s)
    {
      if (a != b && a+b == v) 
        r++;
    }
  if (r == 0) 
  {
    s.push(v);
    --n;
  }
  if (n != 0)
     return S(n,v+1,s)
  else
     return s
}

Test In FireFox / Firebug - Konsole. Einfache Funktion:

S(20)

[1, 2, 4, 7, 10, 13, 16, 19, 22, 25, 28, 31, 34, 37, 40, 43, 46, 49, 52, 55]

Erweiterte funktion:

S(10,5)

[1, 2, 4, 8, 16, 32, 63, 94, 125, 156]


2

> <> (Fisch) , 72 65 49 46 Zeichen

1n1-:?!;' 'o2n1-v
v1&no' ':<4&;!?:<
>-:?!;&3+^

Die Eingabe wird an den Interpreter geliefert:

>fish.py stohr.fish -v 10
1 2 4 7 10 13 16 19 22 25

Mein erstes> <> Programm, Vorschläge erwünscht.


Oh gut! Ich hatte gehofft, jemand würde ein> <> Programm schreiben.
Théophile

2

> <> 31 Bytes

4i1nao:?!;2nao1-:?!;$:nao3+$d0.

Liest ein einzelnes Zeichen ein, verwendet seinen Codepunkt (z. B. Leerzeichen = 32) und druckt die Zahlen in jede Zeile ein.


2

Perl6 22/30

Ich werde sehen, ob Perl6 die Reihenfolge für mich herleiten kann.

Dazu habe ich den in Perl6 eingebauten REPL verwendet

$ perl6
> 1,2,4,7...*
Unable to deduce arithmetic or geometric sequence from 2,4,7 (or did you really mean '..'?)
> 1,2,4,7,10...*
1 2 4 7 10 13 16 19 22 25 28 31 34 37 40 43 46 49 52 55 58 61 64 67 70 ...

Hmm, ich sehe das Muster, das Perl abgeleitet hat. Nach 4 addieren Sie einfach 3, um den nächsten Wert zu erhalten.

1,2,4,*+3...*

Das spart ein Zeichen, macht den Code, um eine unendliche Liste der Zahlen in der 13 Zeichen langen Stöhr-Folge zu erhalten.

Dieser Code macht nur in der REPL etwas Sinnvolles, da er das Wesentliche des Ergebnisses für uns ausgibt . Um es zum Drucken zu bringen, müssten Sie Perl explizit anweisen, die Ergebnisse zu drucken.

$ perl6 -e 'say 1,2,4,*+3...*'

( * + 3ist einfach eine Möglichkeit, eine Codereferenz zu erhalten, die 3 zurückgibt, die zu ihrem einzigen Argument hinzugefügt wurde. Andere Möglichkeiten, sie zu schreiben, wären { $_ + 3 }, oder -> $i { $i + 3 }, oder { $^i + 3 }oder. sub ($i){ $i + 3 })


Der kürzeste Weg, um Callable zu erstellen , um die ersten n Elemente zu generieren, besteht darin, einen Teil der Elemente abzurufen .

{(1,2,4,*+3...*)[^$_]} # 22

In einem ungültigen Kontext würden die ersten $_Werte generiert und dann sofort weggeworfen.

In einem anderen Kontext als void wird ein anonymer Codeblock (eine grundlegende Unterroutine ohne Namen) erstellt, der ein Argument enthält.

# store it in a scalar variable
my $sub = {(1,2,4,*+3...*)[^$_]};
say $sub.(5);
# 1 2 4 7 10

# use it immediately
say {(1,2,4,*+3...*)[^$_]}.(5);
# 1 2 4 7 10

# pretend it always had a name
my &Stöhr-first = {(1,2,4,*+3...*)[^$_]};
say Stöhr-first 5;

Wenn Sie wirklich der Meinung sind, dass es einen Namen haben muss, um sich für diese Herausforderung zu qualifizieren, würden Sie dies wahrscheinlich tun:

sub s(\n){(1,2,4,*+3...*)[^n]} # 30

Da dies sauch für den Substitutionsoperator verwendet wird, sind die Parens nicht optional. (Sie könnten es einen anderen Namen gegeben haben, nehme ich an)

say s(5);
# 1 2 4 7 10

Sofern in der Challenge nicht anders angegeben, müssen die Einsendungen für Code-Golf-Challenges vollständige Programme oder Funktionen sein , nicht nur Ausschnitte.
Martin Ender

@ MartinBüttner Fair zu sein 1,2,4,*+3...*schafft eigentlich ein Objekt, das die benötigten Werte generiert. Ich glaube nicht, dass viele Leute in Perl6 tatsächlich so etwas Callable erstellen würden.
Brad Gilbert b2gills

2

Ich sehe, dass es bereits eine VIEL bessere Java-Antwort gibt, aber ich habe eine Weile damit verbracht und werde sie veröffentlichen. auch wenn es scheiße ist.

Java 313 char (+4, um es auf den Bildschirm zu bringen)

import java.util.*;public class S{public static void main(String[] a){
Set<Integer> S=new HashSet<Integer>();S.add(1);int i=1,k=0;
while(S.size()<=new Integer(a[0])){if(S.contains(i)){}else{k=0;for(int j:S){
for(int l:S){if(l!=j){if((j+l)==i)k=1;}}}if(k==0)S.add(i);}i++;}for(int x:S)
{System.out.println(x);}}}

Ich bin immer dankbar, wenn ich Tipps oder Hinweise zur Verbesserung bekomme


1

T-SQL 204

Angenommen, die Eingabe befindet sich in einer Variablen mit dem Namen @N. Ich kann eine Prozedur erstellen, wenn Sie möchten, aber es gibt wirklich keine gute Möglichkeit, STD_IN in T-SQL abzurufen.

Auch yay für moralischen Bonus!

DECLARE @Q INT=0,@B INT=2
DECLARE @ TABLE(A INT)WHILE @N>0
BEGIN
SET @N-=1
WHILE @B>1
BEGIN
SET @Q+=1
SELECT @B=COUNT(*)FROM @ C,@ B WHERE C.A+B.A=@Q
END
INSERT INTO @ VALUES(@Q)SET @B=2
END
SELECT*FROM @

Nett! Ich weiß nicht viel über SQL - wie wird @N hier verwendet? Ich sehe, dass es am Anfang gesetzt ist, aber dann scheint es nicht später verwiesen zu werden.
Théophile

Es sieht so aus, als wäre @Nes das "i" der "for-Schleife".
Jacob

Jacob hat recht. Das @N ist das "i" der for-Schleife, die in SQL eine while-Schleife ist. Im Wesentlichen verknüpft es cross die Tabelle mit sich selbst und findet Paare, die zu @Q hinzugefügt werden. Wenn es mindestens zwei Paare gibt (dh nicht nur eine Zahl mit sich selbst), wird sie übersprungen. Andernfalls wird es der Tabelle hinzugefügt. @ ist der Name der Tabelle.
bmarks

1

Mathematica, 27 Bytes

Hmmm, noch keine Mathematica-Antwort? Hier sind zwei:

NestList[#+3~Min~#&,1,#-1]&
Array[i=1/2;i+=3~Min~i&,#]&

beide definieren eine unbenannte reine Funktion, die eine Ganzzahl empfängt und eine Liste von Ganzzahlen zurückgibt. Dies basiert auf der gleichen Wiederholungsrelation wie meine CJam-Einreichung. Beachten Sie, dass der auf Array-basierende Code von ausgeht 1/2, da die Wiederholungsrelation immer angewendet wird, bevor der Wert zurückgegeben wird.



1

Python - nicht einmal in der Nähe (139)

Die kürzeste Lösung, die ich gefunden habe, ist die folgende:

from itertools import combinations as C
x,i,n=[],1,input()
while len(x)<=n:
 if i not in [sum(y) for y in C(x,2)]:x.append(i)
 i+=1
print n

1

Clojure - 130 118

(defn s[n](last(take n(iterate #(if(<(count %)3)(conj %(+ (apply + %)1))(conj %(+(last %)(second %)(first %))))[1]))))

Ungolf-Version:

(defn stohr [n]
  (last
    (take n
      (iterate #(if (< (count %) 3)
                   (conj % (+ (apply + %) 1))
                   (conj % (+ (last %) (second %) (first %)))) [1]))))

Teile und genieße.


1

Rubin - 108 88

q=->n{*k=1;(m=k[-1];k<<([*m+1..2*m]-k.combination(2).map{|i,j|i+j})[0])while k.size<n;k}

Dies verwendet die Definition der Sequenz.

Mehr lesbare Version:

q=->n{
    *k=1
    (
        m = k[-1]
        k << ([*m+1..2*m] - k.combination(2).map{|i,j|i+j})[0]
    ) while k.size < n
    k
}

print q [10]

[1, 2, 4, 7, 10, 13, 16, 19, 22, 25]


Ruby Golftipps: *k=1statt k=[1]. foo while barstatt while bar;foo;end. [*s..e]statt (s..e).to_a. .mapstatt to_a.map. {|a,b|a+b}statt {|i|i.inject(:+)}.
Histokrat

@histocrat Danke, das ist sehr hilfreich!
Théophile


0

TI-BASIC, 41 27 30 Bytes

Für Ihren Taschenrechner

Input N:For(I,1,N:I:If I>2:(I-2)3+1:Disp Ans:End

0

GML , 67 Bytes

n=argument0;for(i=1;i<=n;i++){t=i;if i>2t=(i-2)*3+1show_message(t)}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.