Створіть послідовність Штера


12

Я вивчаю Рубі і написав свій перший нетривіальний код для вирішення цієї проблеми.

Завдання полягає в генерації перших n елементів послідовності Stöhr , S , який визначається наступним чином:

S [0] = 1

S [n] - найменше число, яке не може бути виражене сумою двох різних попередніх елементів у послідовності.

Таким чином, послідовність починається з 1, 2, 4, 7 і 10. Наступний елемент дорівнює 13, оскільки 11 (= 1 + 10) і 12 (= 2 + 10) - це суми попередніх елементів, але 13 - ні.

Шукаю найкоротший код. У мене в Ruby 108 символів, але, можливо, я зачекаю, щоб побачити, що придумують інші, перш ніж опублікувати його?


Мені подобаються відповіді до цих пір. Зараз, можливо, вже пізно повертатися назад і змінювати вимоги, але, мабуть, я повинен був би згадати, що мене особливо цікавлять рішення, які використовують визначення самої послідовності (тобто код не знає заздалегідь, що в кінцевому підсумку числа зростають на 3). Отже: моральні бонусні бали, якщо ви можете це зробити.
Теофіл,

Така проблема з математичними послідовностями. Якщо ви знаєте викрійку, зазвичай вона буде коротшою.

Ця послідовність є арифметичною без будь-якого використання (?).
користувач75200

@ user75200 Послідовність не є арифметичною, як видно з відмінностей у перших трьох елементах, але підряд, що починається від третього елемента, справді є арифметичним. Він використовується у зв'язку з проблемою поштової марки.
Теофіл

Відповіді:


13

APL, 7

У APL ви можете вибрати, чи бажаєте ви працювати з індексом 0 або індексом 1. Це зробіть, встановивши глобальну змінну ⎕IO ← 0

Якщо ми вирішимо працювати в індексі 0, ми маємо:

+\3⌊1⌈⍳

Пояснення:

⍳    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)

Спробуйте це на tryapl.org


Ви не можете працювати з індексом на основі 1, а потім створити масив від 1 до n і просто додати його до іншого 1? Якщо це можна зробити, чи це коротше?
Оптимізатор

Код, який я отримав, був довшим. Це був мій код для індексу 1, 10 знаків: + \ 3⌊1, ⍳¯1 + Також версія index-0 також працює з аргументом 0, в той час як цей - ні.
Моріс Зукка

Ага. так. APL дійсно просвічував тут ..
Оптимізатор

9

Haskell - 11 21

Ледача нескінченна послідовність

1:2:[4,7..]

Функція, яка повертає щойно поставлену кількість членів (зітхання)

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

Вам потрібно взяти вхід і надрукувати тільки перші nцифри.
Оптимізатор

4
@Optimizer Ну, технічно , вам доведеться "генерувати перші n елементів послідовності Штера" - це не означає, що ви не можете також генерувати решту з них! Це не говорить про те, що ви також повинні взяти вклад. Оригінальний код swish насправді генерує перші n термінів для будь-якого n .
wchargin

1
@WChargin, що намагається переградити, не є новим. Формулювання ОП занадто буквально та отримання додаткового результату, ніж потрібно обом, вважаються стандартними лазівками.
Оптимізатор

2
@Optimizer Власне, лінивий означає, що додаткового результату не буде створено, поки ви цього не попросите, і ви можете запитати будь-які умови, які ви хочете.
швейцарський

1
@swish я не розумію. Що тут ліниве?
Оптимізатор


6

CJam, 14 байт

1l~{_p_3e<+}*;

Тестуйте це тут.

Починається з 1. Тоді 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.";

Це легко узагальнює h -Stöhr послідовності, якщо замінити 3 на 2 h -1 .


6

Brainfuck, 13 символів

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

Або 30 символів, якщо ми хочемо обмежити це n виходами:

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

1
Я думаю, що вам потрібно надрукувати перші nелементи, а не нескінченний потік їх ...
Sp3000

@ Sp3000 Чи загальноприйнято використовувати діаграми як цифровий вхід та вихід? Неможливо знайти на мета. З цим було б досить легко виправити BF-код.
randomra

Особисто я не впевнений, який загальний консенсус для цього, вибачте. У мене теж було проблеми з цим.
Sp3000

для перших n елементів, я думаю, я міг би зробити -> +. <[-> +. <[-> ++. <[-> +++. <]]] (29 знаків), але це не так елегантно . І я не думаю, що мова спеціально обмежена використанням кодів ASCII для введення та виводу.
jgosar

1
Ваш код повинен відповісти на питання, навіть якщо він не такий елегантний. Я б запропонував відредагувати публікацію та виправити відповідь ,->+.<[->+.<[->++.<[->+++.<]]]. (Ви пропустили коду для читання вхідних даних на початку.)
randomra

4

Пітон, 136 байт

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])]

Прямо з визначення. Я не впевнений, наскільки я можу це в гольфі - це, звичайно, набагато довше, ніж я очікував.


3

J, 14 символів

Це просто твердо кодує [1,2, 4+3*k (k=0..n-1) ]послідовність і приймає перше N.

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

.

J, 18 символів

Це один використовує лінійну комбінацію [0,1,2,3...], [1,1,0,0...]і [0,1,1,1...]. Повинен бути коротшим, але не може здатися, що це гольф.

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

3

Прелюдія , 32 20

Редагувати: ... з подвійними голосами зараз!

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

Це передбачає, що інтерпретатор Python с NUMERIC_OUTPUT = True. Як і у поданні Brainfuck, ця відповідь передбачає, що введення подається у вигляді кодової точки. Це почасти, щоб привернути більше уваги до цієї мета-дискусії (і почасти тому, що я люблю Прелюдію). Отже, якщо ви хочете надрукувати перші 32 числа, скажімо, вам потрібно поставити пробіл на STDIN. Звичайно, це означає, що є верхня межа дійсних даних, але ця відповідь все одно не виграє, тому я думаю, що в межах обмежень Прелюдії це нормально.

Пояснення

У прелюдії всі рядки виконуються паралельно, у яких рядок має власний стек, ініціалізований до нескінченної кількості нулів. Є лише один покажчик інструкцій (вказує на стовпці), тому якщо ви введете цикл на один голос, всі інші голоси будуть циклічно разом з ним.

У наступному я перекладаю код, щоб я міг коментувати рядки замість стовпців:

?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

Як рекурсивна функція, заснована на визначенні проблеми

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

Використовуючи візерунок 1,2, 1 + 3 * k: 58

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

Бічна примітка: пошук послідовності h-Stöhr (перевірка суми до hчисел замість всього 2). RФункція намагається все possibile суми вище заданого числа елементів списку.

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

Невикольований приблизно еквівалентний (і сумісний з ES5)

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
}

Тест в консолі FireFox / FireBug. Проста функція:

S(20)

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

Додаткова функція:

S(10,5)

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


2

> <> (риба) , 72 65 49 46 символів

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

Вхід подається для перекладача:

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

Моя перша> <> програма, оцінені пропозиції.


О добре! Я сподівався, що хтось напише програму.
Теофіл

2

> <>, 31 байт

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

Читає в одному знаку, використовує свою кодову точку (наприклад, пробіл = 32) і друкує числа по одному на кожному рядку.


2

Perl6 22/30

Я буду бачити, чи Perl6 може вивести послідовність для мене.

Для цього я використав REPL, вбудований у Perl6

$ 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 ...

Гм, я бачу схему, яку вивів Перл. Після 4, щоб отримати наступне значення, ви просто додасте 3.

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

Що зберігає один символ, роблячи код, щоб отримати нескінченний перелік чисел у послідовності Stöhr довжиною 13 символів.

Цей код є лише корисним у REPL, оскільки він друкує суть результату для нас. Щоб домогтися друку в іншому випадку, вам доведеться прямо сказати Perl, щоб роздрукувати результати.

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

( * + 3це просто спосіб отримати посилання на код, який повертає 3, доданий до цього лише аргументу. Інші способи його написання були б { $_ + 3 }, або -> $i { $i + 3 }, або { $^i + 3 }або sub ($i){ $i + 3 })


Найкоротший шлях , щоб створити що - то може бути відкликаним генерувати перші п елементи, щоб отримати зріз елементів.

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

У недійсному контексті, який би генерував перші $_значення, негайно викидайте їх.

У будь-якому іншому, ніж недійсний контекст, він створює анонімний блок коду (основна підпрограма без імені), який бере один аргумент.

# 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;

Якщо ви дійсно думаєте, що у нього повинно бути ім'я, щоб визнати дійсним для цього виклику, ви, ймовірно, зробите це:

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

Хоча, оскільки sвін також використовується для оператора підстановки, називати це паролями необов'язково. (Ви могли б дати йому інше ім’я, я думаю)

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

Якщо в виклику не вказано інше, подання на код викликів для гольфу повинно бути повноцінними програмами або функціями , а не лише фрагментами.
Мартін Ендер

@ MartinBüttner, щоб бути справедливим, 1,2,4,*+3...*фактично створює об'єкт, який генерує необхідні значення. Я не думаю , що багато людей на насправді створити що - то може бути відкликаним навколо що - щось подібне в Perl6.
Бред Гілберт b2gills

2

Я бачу, що вже набагато краща відповідь на Java, але я витратив час на це, і я збираюся його відправити. навіть якщо це смокче.

Java 313 char (+4, щоб розмістити його на екрані)

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);}}}

завжди вдячний, щоб отримати будь-які поради чи вказівки щодо вдосконалення


1

T-SQL 204

Передбачається, що вхід знаходиться в змінній, що називається @N. Я можу зробити процедуру, якщо хочете, але насправді не існує хорошого способу отримати STD_IN в T-SQL.

Крім того, так, моральний бонус!

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 @

Приємно! Я мало знаю про SQL - як тут використовується @N? Я бачу, що він встановлений біля початку, але потім, здається, не пізніше на нього посилаються.
Теофіл

Схоже, @Nце "я" з "для циклу".
Яків

Яків прав. @N - це "i" циклу for, який є циклом в SQL. По суті, він перетинає об'єднує таблицю з собою і знаходить пари, які додають до @Q. Якщо є хоча б дві пари (тобто не просто число з самим собою), то це пропускає його. В іншому випадку він додає його до столу. @ - назва таблиці.
позначки

1

Математика, 27 байт

Гммм, все ще немає відповіді Mathematica? Ось два:

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

обидва визначають неназвану чисту функцію, яка отримує ціле число і повертає список цілих чисел. Це ґрунтується на тому самому рецидиві, що і в моєму заяві CJam. Зауважте, що Arrayкод на основі починається з 1/2, тому що відношення повторення завжди застосовується до повернення значення.



1

Пітон - навіть не близько (139)

Діючи за припущенням, що це було нелегко підрахувати, як це зробили інші, найкоротше рішення, яке я знайшов, знаходиться нижче:

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]))))

Версія без гольфу:

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

Діліться та насолоджуйтесь.


1

Рубі - 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}

При цьому використовується визначення послідовності.

Більш прочитана версія:

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
}

друк q [10]

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


Підказки Ruby Golf: *k=1замість k=[1]. foo while barзамість while bar;foo;end. [*s..e]замість (s..e).to_a. .mapзамість to_a.map. {|a,b|a+b}замість {|i|i.inject(:+)}.
гістократ

@histocrat Спасибі, це дуже корисно!
Теофіл


0

TI-BASIC, 41 27 30 байт

Для вашого калькулятора

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.