| Bytes | Lang | Time | Link |
|---|---|---|---|
| 016 | Uiua | 240919T000025Z | nyxbird |
| 043 | Clojure | 240917T203406Z | Martin P |
| 036 | PowerShell Core | 210803T023912Z | Julian |
| 042 | R | 210801T153748Z | Dominic |
| 022 | Haskell | 210801T014142Z | Unrelate |
| 046 | tinylisp | 210801T012736Z | DLosc |
| 057 | Racket | 210731T231852Z | D. Ben K |
| 007 | Jelly | 210730T223631Z | Nick Ken |
| 042 | Python 3.8 prerelease | 210730T013754Z | hyper-ne |
| 045 | Perl 5 | 210730T111721Z | Kjetil S |
| 029 | APL Dyalog Unicode | 210730T012508Z | Adá |
| 022 | K ngn/k | 210730T060501Z | Razetime |
| 027 | J | 210730T051357Z | Jonah |
| 037 | JavaScript | 210730T014237Z | tsh |
| 026 | Wolfram Language Mathematica | 210730T023433Z | att |
| 036 | Factor | 210730T012953Z | Bubbler |
Uiua, 16 bytes
◌⍢(^!°⊂⊂|±⧻):[]¤
◌⍢(^!°⊂⊂|±⧻):[]¤
:[]¤ # s -> [s] []
⍢( |±⧻) # repeat while the top isn't []:
°⊂⊂ # [s r?] [r1 r2...] -> s [r? r1 r2...]
^! # s [...] -> f(s) [...]
◌ # [] [...] -> [...]
I initially tried to do something with catching an error from °⊟, but this ended up being shorter.
Clojure, 43 bytes
#(seq(iteration %2 :initk % :vf :v :kf :s))
Call with state and function. Function has to return either nil or hash-map with keys :s (new state) and :v (value).
Example:
(#(seq(iteration %2 :initk % :vf :v :kf :s))
137
#(when-not (zero? %)
(let [digit (mod % 5)
next-state (int (/ % 5))]
{:s next-state :v digit})))
=> (2 2 0 1)
PowerShell Core, 36 bytes
for($k,$a=$args;$a){$a,$u=&$k $a;$u}
Takes two parameters, a function $k and the initial value $a
-1 byte thanks to mazzy!
R, 43 42 bytes
u=function(s,l=f(s))if(1/l)c(l[2],u(l[1]))
Recursive function using helper function f to to the unfolding.
f must output the fixed non-integer value Inf to represent that the list has ended (a more natural value in R would be NULL or NA, but the functions is.null() and is.na() are each much less golfy than the simple test 1/x [truthy for all integers, falsy only for Inf])
Haskell, 22 bytes
f#x=do(s,v)<-f x;v:f#s
Function is expected to return a list [(state, value)] or an empty list. (Footer converts from the conventional/expected use of Maybe.)
f#x= Define a function (#) on arguments f and x, returning
do <-f x; the concatenation for each element of f called on x
(s,v) providing the new state and value
v: of the value prepended to
f#s (f#) called on the new state.
Was this before I remembered MonadFail is a thing (never mind I'm not even using it anymore):
Haskell, 26 bytes
f#x|s:v<-f x=v++f#s|1>0=[]
Function is expected to return a list [state, value] or an empty list.
tinylisp, 46 bytes
(d U(q((S F)(i(F S)(c(h(t(F S)))(U(h(F S))F))(
Ungolfed
Implements the spec directly:
(load library)
(def unfold
(lambda (val func)
(if (func val)
(cons
(head (tail (func val)))
(unfold (head (func val)) func))
nil)))
This approach is pretty inelegant: it's not tail-recursive, and it calls the function three times at each step. If I were going to implement unfold for the standard library, it would look more like this (using a helper function _unfold):
(def _unfold
(lambda (func return-val accum)
(if return-val
(_unfold func
(func (head return-val))
(cons (head (tail return-val)) accum))
(reverse accum))))
(def unfold
(lambda (func val)
(_unfold func (func val) nil)))
Racket, #lang racket, 57 bytes
(define(u s f)(match(f s)[`(,z,x)(cons x(u z f))][_'()]))
The function f can return anything other than a list of two values to indicate stop.
Not the most interesting racket solution: no tail-call recursion, so is bounded by memory usage. It would be more fun (and not difficult) to write a #lang that supplies unfold as part of its runtime—then there would be a 0-byte solution :)
We (unexpectedly?) save a few bytes by eliminating spaces between ,z,x and _'() in match clauses. I expected each to coalesce into a single identifier, but (un)quoting took precedence. The remaining whitespace (6 spaces, by my count) is required.
Jelly, 7 bytes
Ṫv@¥ƬFḊ
A dyadic link taking the start value as its left argument and the Jelly code for the relevant function to unfold as its right. It expects the return value of this link to be an empty list if we’re done, otherwise a list of [next value for result, next value for function]. Returns a list of integers.
Python 3.8 (pre-release), 42 bytes
u=lambda f,x:(r:=f(x))and[r[1],*u(f,r[0])]
-1 byte thanks to Noodle9
-4 bytes thanks to Shaggy
Assumes falsy output for the end case and a pair otherwise (any subscriptable value with at least two elements). Since a list of falsy values is still truthy, this works perfectly fine.
APL (Dyalog Unicode), 32 29 bytes
Full program, prompting for s and then for f.
¯1↓r⊣⎕{1↓r,∘⊃←⍺⍺⍵}⍣{⍬≡⍺}⎕⊣r←⍬
r←⍬ initialise the result variable to the empty list
⎕⊣ dismiss that in favour of s from stdin
⎕{…}⍣{⍬≡⍺} get f from std and use it as follows until the result is the empty list:
⍺⍺⍵ apply f to the current s (returning [e,t] or [])
r,∘⊃← extend r with the first value from that (e or 0)
1↓ drop the first value from that (leaving [t] or [])
r⊣ discard that (i.e. the last computed value, i.e. []) in favour of r
¯1↓ drop the last value (0)
K (ngn/k), 22 bytes
{-1_1_*'|'{x}(y@*:)\x}
call with f[n,s].
s should return an array (nextState;digit) and return a falsy value when it's supposed to end.
I can remove {x} but that would make the function stop on a repeated state. Although that is unlikely, it doesn't seem right to reject that.
Explanation
{-1_1_*'|'{x}(y@*:)\x}
\x
iterate on first arg, producing array
(y@*:) apply second arg(function) to the first elem of the iteration
{x} stop if the iteration is falsy
|' reverse each array
*' take first element of each
-1_1_ remove first and last element
J, 27 bytes
1 :'[:(#~2|i.@#)(,u@{:)^:_'
This is J adverb, which modifies a verb returning (new element, new state) to create the required unfold verb.
(,u@{:)^:_Keep appending unfold's results until a fixed point, re-applying the verb to the last element on every iteration.[:(#~2|i.@#)Keep only odd indexed elements, ie, the elements only, and discard the states and the starting value.
JavaScript, 37 bytes
f=>g=s=>(a=f(s))?[a[1],...g(a[0])]:[]
((state: T) => [next_state: T, val: S]?) => (state: T) => S[]
Wolfram Language (Mathematica), 26 bytes
f=#@#2/.{a_,b_}:>b<>#~f~a&
Input [f, s]. Returns a StringJoin of elements. Expects an empty list to indicate the list has ended.
To output a list, +6 bytes:
f=#@#2/.{a_,b_}:>{b,##&@@#~f~a}&
Factor, 37 36 bytes
[ collector [ follow ] dip 1 head* ]
-1 byte thanks to @chunes
Takes initial-value and quotation on the stack, and returns a vector. The input quotation should return next-state next-value on the stack, or f f to terminate.
some-quot collector [ high-order-func ] dip is a pattern to snatch the top of the stack of every call of some-quot into a vector. Unfortunately, it collects the top of the stack before follow can detect that the loop has ended, so the resulting vector has a dummy element at the end. 1 head* removes it.