| Bytes | Lang | Time | Link |
|---|---|---|---|
| 156 | Microsoft Excel | 241030T164949Z | General |
| 100 | Nim | 221025T080134Z | Kirill L |
| 067 | PHP | 221018T180146Z | Titus |
| nan | C# .NET Core 107 | 221016T130454Z | rene |
| 043 | C clang | 221015T140133Z | jdt |
| 064 | C++ clang | 221015T175806Z | c-- |
| 042 | Dart | 221015T201409Z | lrn |
| 040 | Rust | 221015T102955Z | corvus_1 |
| 010 | Husk | 221015T114215Z | Dominic |
| 076 | Python | 221014T143802Z | solid.py |
| 101 | C++ clang | 221015T094108Z | AZTECCO |
| 011 | Pyth | 221015T085933Z | CursorCo |
| 054 | R | 221014T214450Z | Dominic |
| 013 | Japt | 221014T173815Z | Kamil Dr |
| 033 | Factor | 221014T173929Z | chunes |
| 018 | Raku | 221014T184423Z | Sean |
| nan | 221014T174815Z | bigyihsu | |
| 026 | JavaScript ES6 | 221014T144941Z | Arnauld |
| 059 | Python | 221014T153513Z | loopy wa |
Microsoft Excel, 156
Phew... this is quite difficult in a language that doesn't let you alter variables or have objects.
It doesn't quite meet the requirements, but I think it fits the spirit of the challenge. In this implementation, the flip flop function has to encode its output in a LAMBDA that returns the actual value. Unfortunately, that was the best I could figure out. I felt this was a better compromise than just letting myself add a parameter to the flip-flop function. Fortunately, it's easy to decode.
Golfed:
LAMBDA(a,b,LET(f,LAMBDA(g,o,d,e,LAMBDA([v],IF(ISOMITTED(v),o,IF(g(v),d(d),e(e))))),p,LAMBDA(s,f(a,0=1,LAMBDA(u,f(b,1=1,LAMBDA(_,f(a,1=1,u,s)),u)),s)),p(p)))
Ungolfed:
LAMBDA(a,b,
LET(
f,LAMBDA(g,o,d,e,LAMBDA([v],IF(ISOMITTED(v),o,IF(g(v),d(d),e(e))))),
p,LAMBDA(s,
f(a,0=1,LAMBDA(u,
f(b,1=1,LAMBDA(_,
f(a,1=1,u,s)
),u)
),s)
),
p(p)
)
)
Usage example:
=LET(
makeFF,LAMBDA(a,b,LET(f,LAMBDA(g,o,d,e,LAMBDA([v],IF(ISOMITTED(v),o,IF(g(v),d(d),e(e))))),p,LAMBDA(s,f(a,0=1,LAMBDA(u,f(b,1=1,LAMBDA(_,f(a,1=1,u,s)),u)),s)),p(p))),
MAP(
SCAN(
makeFF(LAMBDA(x,x=3),LAMBDA(x,x=7)),
SEQUENCE(10),
LAMBDA(x,y,x(y))
),
LAMBDA(x,x())
)
)
How does it work?
- We take advantage of the fact that
SCANcan hold intermediate values by storing aLAMBDA. - This lambda returns the following:
- If called with no arguments, the value of the flip-flop
- If called with a value, returns another lambda that represents the state of the flip-flop. This one can also be called with no arguments or a value argument (and so on, recursively).
- So per iteration of
SCAN, we call it with the input value to get an array of lambdas, then we callMAPto "decode" them by invoking these with no arguments.
How does this track the state of the flip-flop?
- The flip-flop generator returns a state machine. Each state is also a
LAMBDA.- Input
v - State 1: Value is
FALSE, goes to 2 if a(v), else goes to 1 - State 2: Value is
TRUE, goes to 3 if b(v), else goes to 2 - State 3: Value is
TRUE, goes to 2 if a(v), else goes to 1 - If
vis omitted, output the state.
- Input
- The function
fis a helper for defining the state property (return value and transition functions)
Why can't you...
- Just use
SCANto track the state directly? Because this would require passing the state to the flip-flop. The flip-flop only takes the one value argument according to the challenge rules. Otherwise, you'd have to call the flip-flop generator on every iteration ofSCAN, which is also not valid. - Use recursion instead of
MAP+SCAN? I probably could have, but I'd still have to unpack the value. This was just easier to think about. You'd have to do that for Google Sheets, though, because you're not currently allowed to call LAMBDA's stored in arrays.
Nim, 100 bytes
import sugar
var s,t=off
proc f(x,y:int->bool):proc=(z:int)=>(s=s or z.x;t=s;s=s and not z.y;s or t)
Works with int-typed inputs, uses a couple of globals to store the current and previous states.
Unfortunately, Nim doesn't let us omit type annotations, unless we are supplying the lambda directly as an argument to a higher-order function (as in test cases in the footer), so this ends up rather verbose. Importing syntax sugar macros -> and => allows getting rid of some repetitive annotations and thus, pays off by a few bytes.
As a bonus, Nim also allows defining operators, so that we can mimick Ruby's behavior precisely:
PHP 67 bytes
function f($i,$a,$b){static$k=0;$r=$k;return$r|$k^=($k?$b:$a)($i);}
$k must be copied to a temp variable because the ^= is executed before the |,
although both operators are LTR.
Just define your two functions and give them to f as parameters within the loop.
The functions may be anonymous or named, or even predefined.
e.g.
# example 1
$a=function($i){return$i==2;} $b=function($i){return$i==8;}
for($i=0;$i<=10;$i++) f($i,$a,$b) && print "$i ";
or
# example 2
function a($i){return$i%5==0;} function b($i){return$i%5==2;}
for($i=0;$i<=10;$i++) f($i,'a','b') && print "$i ";
# important: function names must be quoted to avoid "undefined constant" error (in PHP 8)
or
# other example
for($i=0;$i<=10;$i++) f($i,'intval',function($i){return$i<5;) && print "$i ";
# prints 1 2 3 4 5 6 7 8 9 10
# ('$i<5' is irrelevant because testing 'intval' immediately resumes the printing)
C# (.NET Core) 120 117 107 bytes
Here is a C# version based of the Dart and Go examples.
Func<Func<int,bool>,Func<int,bool>,Func<int,bool>>f=(l,r)=>{var s=1<0;return v=>l(v)?s=!s:r(v)?!(s=!s):s;};
Shaved off 3 bytes by replacing
falsewith1<0and a non needed space. Hat tip to jdtShaved off 10 bytes by not doing boolean wizardry
Ungolfed main version:
var flipflop = new Func<Func<int,bool>, Func<int, bool>, Func<int,bool>> ( (condition1,condition2) => {
var flipflop = false;
return new Func<int,bool>(value => {
if (condition1(value))
{
flipflop = !flipflop;
} else if (condition2(value)) {
flipflop = !flipflop;
return true;
}
return flipflop;
});
});
How you use it:
var flop = f(v => v == 2, v => v == 8);
for(var x = 0; x< 11; x++)
{
if (flop(x)) {
Console.WriteLine(x);
}
}
C# (.NET Core), 91 bytes
Using a delegate as proposed by jdt
delegate bool d(int i);Func<d,d,d>f=(l,r)=>{var s=1<0;return v=>l(v)?s=!s:r(v)?!(s=!s):s;};
C (clang), 43 bytes
Reusable form as proposed by AZTECCO
#define f(x,a,b)static m;m|(m^=m?x b:x a)&&
C (clang), 41 40 bytes
-1 byte thanks to ceilingcat!
t;f(a(),b(),i,*r){*r=t|(t^=(t?b:a)(i));}
C++ (clang), 64 bytes
[t=0](auto p){return[=](auto x)mutable{return t|(t^=p[t](x));};}
Port of @Arnauld's JavaScript answer.
Instead of t being a default parameter, it's captured and initialized to 0. The function returns a mutable lambda which captures this t by value along with the predicates container.
This other lambda (the closure) does the heavy lifting, it's declared mutable because it's member t will alternate between the values 0 and 1.
We could save a byte by making the predicates take an int x but it would no longer be generic.
Dart, 42 bytes
f(f,s,[b=1<0])=>(i)=>b?b|(b=!s(i)):b=f(i);
You use it as:
void main() {
var flipflop = f((i)=>i % 3 == 0, (i) => i % 7 == 0);
for (var i = 1; i < 15; i++) {
if (flipflop(i)) print(i);
}
}
Which prints 3,4,5,6,7,9,10,11,12,13,14.
It even allows you to pass in an extra Boolean to make it the active state.
In a less horribly mangled and more typed version, it would be:
bool Function(T) flipflop<T>(bool Function(T) from, bool Function(T) until) {
bool b = false;
return (T value) {
if (b) {
b = !until(value);
return true;
}
b = from(value);
return b;
}
}
Rust, 40 bytes
|f|{let mut t=0;move|x|t|{t^=f[t](x);t}}
An expression compatible with fn([fn(T)->usize; 2])->impl Fn(T)->usize for any T. (Yes I know impl Trait can't be used as a return type for fn pointers)
Husk, 12 10 bytes
%2ṁ§≠²o⁰←ḣ
%2ṁ§≠²o⁰←ḣ # 2-argument function,
# which yields a partially-applied function
# requiring 1 further argument:
ḣ # 1..further argument
ṁ # map over this and return sum
§≠ # absolute differences between
² # function arg2 applied to each element, and
o⁰ # function arg1 applied to
← # each element plus 1;
%2 # modulo 2.
Example usage f₁₂₃ḣ20
f # filter
ḣ20 # 1..20
# keeping only truthy results of
₁ # function returned by function on line 1
# called with arguments:
₂₃ # functions on line 2 and line 3
Python, 76 bytes
-1 byte thanks to py3_and_c_programmer
Takes as input an element i, two lambda functions a and b while using a global variable t to toggle between the true & false cycles.
def f(i,a,b):
global t
if~t&a(i):t=1
if t&b(i):t=0;return 1
return t
t=0
C++ (clang), 123 101 bytes
struct F{int r=0;template<class A,class B>int operator()(A a,B b,int t){return r|(r^=r?b(t):a(t));}};
- actually we can go to 92 Bytes if we just implemented a class function h for example but it's no more exactly a closure.
Assumes predicates take int type, generalize also predicates will cost a few Bytes.
Due to implicit type conconversion can work with strings.
Struct F is a closure with operator () defined to behave flipFlop.
Saved 22 Bytes by templatizing operator () instead of the entire class.
Approach stolen from @Arnauld answer where r keeps the state of flipFlop.
Pyth, 11 bytes
L+Z=?Z!PbOb
Pyth doesn't have any way to take functions as arguments, nor any way to return a function. So here we do the next best thing, which is to define a function which will implement the required behavior on the two functions O and P. That is to say that when we call y it will flip-flop on whatever O and P are defined as. The try it online link above links to a full working example which is the same as the first example in the question, I'll explain below.
DOdRqd2; define O(d): (d==2)
DPdRqd8; define P(d): (d==8)
L+Z=?Z!PbOb implement y as the flip-floperator
VQyN loop N over range(0,input()) and print the output of y(N)
And the actual flip-floperator
L define y(b)
+Z sum of previous output and
?Z ternary on previous output
!Pb not P(b) if Z currently True
Ob O(b) if Z currently False
= assign result of ternary to Z
R, 54 bytes
{x=F;function(f,g)function(y){x<<-(z=x|f(y))&!g(y);z}}
(or 52 bytes using a global variable to save the current state)
R, 37 bytes (non-competing)
{x=F;function(f,g){x<<-(z=x|f)&!g;z}}
Doesn't fit the written spec of the challenge (the function %..% returns truthy/falsy, rather than a function), but it seems to very well mimic the described behaviour of Ruby's ...
Usage example (to mimic the Ruby example in the challenge):
for(i in 1:20){
if((i==2)%..%(i==8))print(i)
}
Japt, 29 13 bytes
Ï{T|(T^=YgXgT
Defines a function which accepts an array of predicates as its input, and returns the flip-flop function. Theoretically should work on strings, numbers, or arrays as the input for the predicate, but I've only tested with numbers.
Ï{T|(T^=YgXgT
# Initialize T = 0
Ï # Define a function with argument X (an array of predicates):
{ # Return a function with argument Y:
T # Current value of T
| # Bitwise OR
(T^= # T XOR-equals the following:
XgT # Get the function in X at index T
Yg # Apply it to Y
A 16 byte alternative doesn't use a global variable, so could be used to define multiple flip flops.
Factor, 33 bytes
[ '[ _ _ bi on t get swap off ] ]
Expects the false-making predicate first and the true-making predicate second.
[ ... ]A quotation (anonymous function)...'[ ... ]...that creates a quotation (anonymous function)._ _Slot the predicates into the holes.biCall both predicates on the inner quotation's input value (integer).onHere's where it gets tricky. In Factor, you can use any value as a variable (key) to store something. So what I am doing here is using the result of the true-making predicate to store the valuet. It's a little strange to use a canonical boolean value to store a possibly different boolean value, but this is code golf. It's not supposed to make sense, it's just supposed to be short.t getGet the value that is stored int. This is the result that will be returned from the quotation. This must be done after storing the result of the true-making predicate but before storing the result of the false-making predicate in order to get the 'inclusive' behavior we are looking for.swapBring the result of the false-making predicate to the top of the stack.offStorefin the result of the false-making predicate.
Raku, 18 bytes
->\f,\g{&{f ff g}}
Raku has a built-in operator ff that does exactly what's asked for. My answer is mostly just setting up the functional plumbing around it.
-> \f, \g { ... }is an anonymous subroutine taking two arguments.&{ ... }is the anonymous subroutine the top-level subroutine returns. Not having an explicit signature, it takes its argument in the topic variable$_, which the flip-flop operator implicitly checks against.f ff greturns false until the topic variable smartmatches againstf, that is,$_ ~~ f, then keeps returning true until$_ ~~ g. Sincefandgare functions, those smartmatches are equivalent tof($_)andg($_).
Go, 131 bytes, ints only
func m(l,r func(int)bool)func(int)bool{f:=1<0
return func(t int)bool{if!f&&l(t){f=!f;return f}
if f&&r(t){f=!f;return!f}
return f}}
Go, 132 bytes, generic
func m[T any](l,r func(T)bool)func(T)bool{f:=1<0
return func(t T)bool{if!f&&l(t){f=!f;return f}
if f&&r(t){f=!f;return!f}
return f}}
This solution is fully generic for any type T.
Ungolfed
func makeFlipFlop[T any](l,r func(T)bool) func(T)bool {
flipped := false
return func(t T)bool {
if !flipped && l(t) {flipped = true; return true}
if flipped && r(t) {flipped = false; return true}
return flipped
}
}
JavaScript (ES6), 26 bytes
Expects [ first_predicate, second_predicate ], where both predicates are functions taking a single parameter.
Returns a flip-flop function which itself returns either 0 or 1.
(p,k=0)=>v=>k|(k^=p[k](v))
Commented
( // flip-flop generator taking:
p, // p[] = pair of predicate functions
k = 0 // k = flip-flop status, initialized to 0
) => //
v => // anonymous function taking a parameter v
k | ( // always return 1 if k is already set
// (because we must still return 1 when the 2nd
// predicate is triggered)
k ^= p[k](v) // toggle k if the result of p[k](v) is true
) //
Python, 59 bytes
lambda a,b:lambda x,t={0}:t.add((o:=t.pop()|a(x))>b(x))or o
Anonymous function returning an anonymous function that keeps state in a mutable initialiser.