CJam, 34 33 байта
int i,w,t,y;int[]F(int n){var r=new int[n--];for(;i<n;y=0){w=r[i++]-i;for(t=0;y<i&&t<1;)t=w==r[y++]?1:0;r[i]=w>0&&t<1?w:r[i-1]+i;}return r;}
Попробуйте онлайн.
Пример запуска
0,1,3,6,2,7,13,20,12,21,11,22,10,23,9,24,8,25,43,62
Как это работает
$a-join","
||answer||
Шестиугольник, 212 байт
$n=Read-Host;$a=@(0);$n-=1;1..$n|%{$x=$a[-1]-$_;if($x-gt0-and!($a-like$x)){$a+=$x}else{$a+=$x+2*$_}};$a
Попробуйте онлайн!
Вход: одно положительное целое число \$n\$ на n=a=0
v=[]
exec'a+=[n,-n][a+n in v];print a;n-=1;v+=a,n;'*input()
.
Выход: все члены последовательности Рекамана до \$A(n)\$ включительно, разделенные пробелами (обратите внимание, что это означает, что программа напечатает всего \$n + 1\$ членов).
Расширенный
Объяснение
Извиняюсь, если это сбивает с толку, но я впервые работаю с Hexagony, так что будьте уверены, меня это тоже смущает.
Пусть \$n = 6\$.
edi
reads \$n\$ from ecx
Указатель инструкций (IP) начинается в северо-западном углу и движется по черному пути.
n
и сохраняет его в текущем крае памяти. edi
and looping through the rest of the black path.
This loop continues until the current edge is 0, at which point the graph looks like so:
Затем мы копируем \$n\$ три раза, сохраняя при этом указатель памяти. n
edge now stores a value \$i\$ from 0 to 6; later, these same edges will store the terms \$A(i)\$ of the sequence as they are computed.
Each int32_t
Мы также переворачиваем указатель памяти и уменьшаем край, на который он указывает.
-
.intel_syntax noprefix
.globl recaman
// input: ECX: n, EDI: u32[n]
// output: stored to EDI
recaman:
// Save the array pointer to ESI
mov esi, edi
// EAX (A(n)) = 0
xor eax, eax
// EDX (n) = 0
cdq
// Store first word
jmp .Lstore
.Lloop:
// A(n - 1) - n
sub eax, edx
// if negative, do A(n - 1) + n
js .Lneg_or_dup
.Lnot_neg_or_dup:
// We need to save both EDI and ECX, so we do a lazy PUSHA/POPA.
pusha
// EDI = start of array
mov edi, esi
// ECX = current output length
mov ecx, edx
// Search for A(n - 1) - n
repnz scasd
// restore registers
popa
// If the zero flag is set, we found a match.
// If not, go directly to store
jnz .Lstore
.Lneg_or_dup:
// Convert A(n - 1) - n to A(n - 1) + n by adding n * 2
// EAX = EAX + EDX * 2
lea eax, [eax + 2 * edx]
.Lstore:
// Store a u32 to EDI and autoincrement
stosd
// Increment length
inc edx
// Decrement counter and loop if non zero
loop .Lloop
// Return
ret
is used for several purposes, but never to store anything permanently because it is frequently overwritten by other operations.
-
00000034: 89 fe 31 c0 99 eb 11 29 d0 78 0a 60 89 f7 89 d1 ..1....).x.`....
00000044: f2 af 61 75 03 8d 04 50 ab 42 e2 eb c3 ..au...P.B...
is generally used as a temporary variable, but it remains 0 for the last \$i\$ in the sequence, telling the program when to stop.
-
(,][`(+2*#)@.(e.+.0>[)~{:-#)^:(]`0:)
stores the value of \$A(i - 1)\$
-
tu+G-eG_W|g0J-eGH}JGHQ]0 Implicit: Q=eval(input())
u Q Reduce [0-Q)...
]0 ... with initial value G=[0], next value as H:
eG Last value of G (sequence so far)
- H Take H from the above
J Store in J
g0J 0 >= J
}JG Is J in G?
| Logical OR of two previous results
_W H If the above is true, negate H, otherwise leave as positive
-eG Subtract the above from last value in G
+G Append the above to G
The result of the reduction is the sequence with an extra leading 0
t Remove a leading 0, implicit print
straightforwardly stores a copy of \$i\$ or, later, \$A(i)\$
В конечном итоге IP снова перемещается в верхний левый угол, перепрыгивая через tu+G-eG_W|g0J-eGH}JGHQ]0
prints the decimal representation of VQ=+Y?Y?|>NeYhxY-eYN+eYN-eYNZ)Y
Это формирует скелет нашей структуры памяти. 0X push 0 to main stack and store it in X register, which will store A(n - 1)
z push an empty array that will be used to store the sequence
,D pop input from input stack, execute the rest of the program that many times
xi-Y push (x-register - iteration-index) and store it in the Y register
this is (A(n - 1) - n)
0> test if (A(n - 1) - n) is greater than 0 (a)
ny# count number of times (A(n - 1) - n) occurs in the sequence so far (b)
> test if (a) > (b)
y (A(n - 1) - n)
xi+ A(n - 1) + n
? if/else; choose between the two values based on the condition
X store the result in the X register
Q print without popping
+ append to sequence array
.
Next, we move the memory pointer to n
Каждый
A(n - 1)
Edge также имеет 4 смежных ребра, которые используются для последующих вычислений. Давайте объясним их сейчас: É╖C8½ΔL▄░▬L+≡ΩSa⌂¼╧
terminates the program immediately; otherwise, we move to *f(n){int*a=calloc(4,n),i=0,j,k,m;for(;~i+n;a[i]=k+(m|k<1)*2*i)for(k=a[i++]-i,m=0,j=i;j--;)m=k-a[j]?m:1;n=a;}
Как только программа завершает инициализацию своего графа памяти, она ответвляется от черного пути на красный путь возле северо-восточного угла.
bash$ java -jar clojure-1.6.0.jar rec.clj 14
[0 1 3 6 2 7 13 20 12 21 11 22 10 23]
(defn f[m a]
(let [n (count a)
b (last a)
x (- b n)
y (if (and (> x 0) (not (.contains a x))) x (+ b n)) ]
(if (= m n) a (f m (conj a y))) ) )
(println (f (read-string (first *command-line-args*)) [0]) )
then prints this space to (defn f[m a](let[n(count a)b(last a)x(- b n)y(if(and(> x 0)(not(.contains a x)))x(+ b n))](if(= m n)a(f m(conj a y)))))(println(f(read-string(first *command-line-args*))[0]))
Первый, bash$ groovy Rec.groovy 14
0 1 3 6 2 7 13 20 12 21 11 22 10 23
to the next m = args[0] as int
a = [0]
(1..m-1).each { n->
b = a[n-1]
x = b-n
( x>0 & !(x in a) ) ? a[n] = x : (a[n] = b+n)
}
a.each{print "$it "}
:
m=args[0] as int
a=[0]
(1..m-1).each{n->b=a[n-1];x=b-n;(x>0&!(x in a))?a[n]=x:(a[n]=b+n)}
a.each{print "$it "}
к def f(x,t=0):
if x:t=f(x-1);t+=2*x*(t*(t>0)in map(f,range(x)))
return t
to и проверить на ноль: function s(n)
a,b={1},{[0]=0}
for i=1,n do
k=b[i-1]-i
c=k+i+i
if (k>0) and (a[k]==nil) then
b[i],a[k]=k,1
else
b[i],a[c]=c,1
end
end
return b
end
before moving to Если оно равно нулю, function s(n)a,b={1},{[0]=0}for i=1,n do k=b[i-1]-i c=k+i+i if(k>0)and(a[k]==nil)then b[i],a[k]=k,1 else b[i],a[c]=c,1 end end return b end
:
int[]f(int n){int[]a=new int[n];a[0]=0;int i,j,k,m;for(i=0;i<n-1;){k=a[i++]-i;m=0;for(j=0;j<i;)if(k==a[j++])m=1;a[i]=m<1&k>0?k:k+2*i;}return a;}
¾ˆ # Initialize the global list with 0
G # for N in [1, input-1] do:
¯ # push the global list
¤N- # subtract N from the last item in the list
D # duplicate
Š # move the copy down 2 spots on the stack
D # duplicate again
0› # check if it is positive
* # multiply, turning negative results to zero
å # is the result already present in the list?
N·* # multiply by N*2
+ # add to the result
ˆ # add this to the list
computes ¾ˆG¯¤N-DŠD0›*åN·*+ˆ
- {(0,{($!=@_[*-1])+@_-@_*2*($!>@_&&$!-@_∉@_)}...*)[^$_]}
, which is really \$A(i - 1) - i\$, and stores it in n=>(g=y=>n-x?g(a[++x]=a.includes(z=y-x)|z<0?+y+x:z):a)(a=[x=0])
:
и установите его на 32 (пробел ASCII): > An(0,34,1)
[1] 0 1 3 6 2 7 13 20 12 21 11 22 10 23 9 24 8
[18] 25 43 62 42 63 41 18 42 17 43 16 44 15 45 14 46 79
is not positive, A = function(s,n,m,i) {
if(m==n){return(s)}
else{
t=i-m
if(t%in%s||t<0){t=i+m}
s=c(s,t)
A(s,n,m+1,t)
}
}
. A=function(s,n,m,i){if(m==n){return(s)}else{t=i-m;if(t%in%s||t<0){t=i+m};s=c(s,t);A(s,n,m+1,t)}}
instead computes function A=f(n)
A=0;for i=1:n-1 b=A(i)-i;A(i+1)=b+2*i;if b>0&&~any(A==b) A(i+1)=b;end;end
+ n=9;f
(\$A(i - 1) + i\$) and stores it in A=0;for i=1:n-1 b=A(i)-i;A(i+1)=b+2*i;if b>0&&~any(A==b) A(i+1)=b;end;end
:
Наконец, мы копируем
Теперь, когда указатель памяти находится на следующем термине, мы копируем его f.m
is positive, we have to make sure it doesn't already exist in the sequence before printing it.
In this case, the G(11) -> 0,1,3,6,2,7,13,20,12,21,11
его G=n=>(i=>{for(r=[t=0];++i<n;)r[i]=t+=i>t|~r.indexOf(t-i)?i:-i})(0)||r
to f=n=>{for(a=[x=i=0];++i<n;)a[i]=x+=x>i&a.indexOf(x-i)<0?-i:i;return a}
:
{$[y>c:#x;o[x,(r;*|x+c)(r in x)|0>r:*|x-c;y];x]}[,0;] / the solution
{ }[,0;] / lambda with first arg set as list containing 0
$[ ; ; ] / if[condition;true;false]
#x / length of x
c: / save as c
y> / y greater than? (ie have we produced enough results?)
x / return x if we are done
o[ ;y] / recurse with new x and existing y
x-c / subtract c from x
*| / reverse first, aka last
r: / save result as r
0> / 0 greater than?
| / or
( ) / do together
r in x / r in x?
( ; ) / use result to index into this 2-item list
x+c / add c to x
*| / reverse first, aka last
r / result
x, / append to x
его {$[y>c:#x;o[x,(r;*|x+c)(r in x)|0>r:*|x-c;y];x]}[,0;]
mirror.
Next, we copy sn Stores the input in register n
[z+z+0r:a]sF Defines the macro F, which:
z+z+ adds twice the stack size/index variable
0r:a resets the "uniqueness" flag to 0 in the array a
In context, F is the "D" in my description above,
changing A(z-1)-z to A(z-1)+z
0 The main loop starts with the previous sequence member on top of
the stack and total stack depth equal to the next index.
Pushing a zero accomplishes both of these things.
[ Start of the main loop M
p Print the previous sequence member, with newline (no pop)
z- Calculate A(z-1)-z
d1>F If that's nonpositive, (F)ix it to be A(z-1)+z
d;a a is my array of flags to see if we've hit this value before
0<F If we have, (F)ix it! (nonzero = flag, since ;a is zero by
default, and also zero if we just (F)ixed and therefore
don't care about uniqueness right now)
ddd Make one copy to keep and two to eat
:a Flag this entry as "used" in the uniqueness array a
zln!<M If our "index variable" is n or less, repeat!
]dsMx End of main loop - store it and execute
Если sn[z+z+d0r:a]sF0[pz-d1>Fd;a0<Fddd:azln!<M]dsMx
and move to отклоняет IP на зеленый путь, где (, # push array [0 .. n-1]
[0]\ # push sequence elements as [0] and reverse stack
{ # foreach element in [0 .. n-1] do:
:m; # store current element in m and discard
.m= # get the previous sequence element
m)-:^ # subtract the current index from it and store in ^
0> # is that number greater than 0?
\.^?)! # is that number new to our sequence?
@& # logically and both checks
{^} # if true, push ^
{^m)2*+} # otherwise, add the index twice and push
if
+ # add new element to our sequence
}/
` # make output pretty
.
(,1,\{:~1$=~)-:^1<\.^?)!!@|^\{~)2*+}*+}/
m=p,=0,
exec"p+=1;k=m[-1]-p;m+=k+2*p*(k*(k>0)in m),;"*input()
print m
computes f=->n{a=[0];(n-1).times{|i|a+=[[b=a[-1]-i-1]-a!=[]&&b>0?b:b+2*i+2]};a}
- λ> r 20
[0,1,3,6,2,7,13,20,12,21,11,22,10,23,9,24,8,25,43,62]
(\$A(i - 1) - A(i)\$) and stores it in l=0:0#1
a§v|a<0||a`elem`r v=v|1<2=0-v
a#b=a+(a-b)§b:l!!b#(b+1)
r=(`take`l)
Затем IP поворачивает к юго-западному углу, в конечном итоге возвращаясь к началу красного пути и начиная цикл заново. |
is exactly zero.
All that's necessary to know is that if {<
Однако, если head
instruction.
в юго-восточном углу разветвляется на юго-восточный, огибая и оставаясь на красном пути. +
is zero, we return to the latest term of the sequence with [
Сначала копируем head
computes \$A(i - 1) + i\$) like above.
We then return to the red path.
Это помещает указатель памяти в такое положение, чтобы последующие циклы могли войти в следующий {
is not zero, we check if the current term is zero:
head
к предыдущему семестру head
mirror.
его . Гексагония рассматривает ноль как отрицательное число, поэтому нам нужно выполнить несколько запутанных ветвлений, чтобы проверить, является ли равно нулю, мы нашли повторяющийся термин, и программа перейдет на желтый путь..
В противном случае он вернется на красный путь в
Если
head
, который выполняет подпрограмму по розовому и синему пути, прежде чем
tail
||answer||
Если
vertical
Если да, то вызываем подпрограмму и возвращаемся на красную дорожку через запутанную серию зеркал.
Если это не так, мы переходим к сравнению следующего члена, возвращаясь к вышеупомянутому.
Изображения созданы с помощью Timwi's
Шестиугольный колорер
и
-
||answer||
Эзотерическая IDE