title: Open or Close the Parentheses

text:
# Question
Title: Open or Close the Parentheses
Every phone needs a calculator app. Because of the limited screen real estate, the developer of mine has decided to save some buttons. Instead of having two dedicated bracket buttons - one for open `(` and one for close `)` \- there is just a single bracket button `()`. It looks something like this:

When the button is pressed, it places a bracket. Based on the input given so far, it predicts whether the bracket should be open `(` or close `)`.

By trial and error, I have found the button to follow these rules:

* If there are no unmatched brackets, the next bracket will **always** be open `(`.
* Else, if the last character is a numeral `0123456789` or close `)` bracket, the next bracket will be close `)`.
* Else, if the last character is an operator `+-*/` or open `(` bracket, the next bracket will be open `(`.

## The challenge

Based on the given input and the rules mentioned above, predict whether the button places an open `(` or close `)` bracket.

## Input

Either a string, an array of characters, or anything equivalent. The input will **only** contain the following characters\*: `0123456789+-*/()`

## Output

An open `(` or close `)` bracket **or** any two consistent values representing them.

## Test cases

```
""                  -> "("
"(1+"               -> "("
"(1+(2/3"           -> ")"
"(1+(2/3)"          -> ")"
"(1+(2/3))-8"       -> "("
"(1+(2/3))-8*("     -> "("
"(1+(2/3))-8*((5"   -> ")"
"(1+(2/3))-8*((5)"  -> ")"
"(1+(2/3))-8*((5))" -> "("

```

## Scoring

This is , so the shortest answer in each language wins.

### Note

* The actual calculator also includes the symbols `.%`, but you don't need to care about those.

# Answer
> 13 votes
# JavaScript (Node.js v11.6.0), 48 bytes

```
a=>/k/.test(eval("try{eval(a+')')}catch(e){e}"))

```

Try it online!

We try to append a character `')'` to the end of expression and `eval` it. Node v11.6.0 (as current version on TIO) may:

* Calculate the expression if the expression is valid
    + The calculate result may only contain characters `/[0-9INafinty]/`
* Report error `SyntaxError: Unexpected token )` if the `)` should not be there
* Report error `SyntaxError: Unexpected end of input` if the `)` is valid there

So we just need to check if the result contains letter `"k"`.

# Answer
> 6 votes
# C (clang) on Linux, ~~82~~ ~~79~~ ~~66~~ 62 bytes

```
c;f(*x){for(c=0;*x;++x)*x&22?:*x&1?--c:++c;c*=*--x&16|*x==41;}

```

Try it online!

Expects a nul-terminated ASCII wide string (4 bytes per character). Returns false (zero) for open bracket and true (nonzero) for close bracket.

* Thank you to @AZTECCO for golfing off 13 bytes!
* And thank you to @jdt for golfing off 4 more bytes. (This required switching to clang; the original answer was for gcc.)

# Answer
> 5 votes
# 05AB1E, ~~18~~ 16 bytes

```
„()S¢Ëžh')«Iθå≠~

```

-2 bytes by outputting `1` for `(` and `0` for `)`.

Try it online or verify all test cases.

**Explanation:**

```
„()        # Push string "()"
   S       # Convert it to a character-list: ["(",")"]
    ¢      # Count the "(" and ")" in the (implicit) input-string
     Ë     # Check whether both are the same
žh         # Push builtin "0123456789"
  ')«     '# Append a ")"
     Iθ    # Push the last character of the input-string
       å≠  # Check that it's NOT in the string "0123456789)"
~          # Bitwise-OR to check if at least one is truthy
           # (after which this is output implicitly as result)

```

# Answer
> 5 votes
# Vyxal, 16 bytes

```
‛()$vO≈9ʀ\)J?tc∨

```

Try it Online!

0 for `(` and 1 for `)`

# Answer
> 5 votes
# Python 2, 48 bytes

```
lambda L:"0">cmp(*map(L.count,"()"))*L[-1:]!=")"

```

Try it online!

Based on @wasif's Python 3 answer; shortened using `cmp` which is not available in Python 3.

True for "("

False for ")"

# Answer
> 5 votes
# Perl 5 -nMv5.10, 23 bytes

```
say!/[\d)]$/||eval&&!$@

```

Try it online!

Prints true/1 for `(` and false/empty string for `)`.

And for eight extra bytes we can print `(` and `)` like this: Try it online 31 bytes. The `eval&&!$@` checks if the input expression have balancing parentheses by using the Perl compiler to check if it compiles.

# Answer
> 4 votes
# GNU AWK, 75 bytes

```
BEGIN{RS=".|"}RT~/\(/{++n}RT~/\)/{--n}END{print n?RT~/[\)0-9]/?")":"(":"("}

```

Try it online!

```
BEGIN{RS=".|"}

```

Starts reading the input one character at a time, which are stored in the `RT` variable, by the way.

```
RT~/\(/{++n}
RT~/\)/{--n}

```

If the character is a `(`, increments `n` by one. If it is `)`, decrements `n` by one.

```
END{print
          n?
            RT~/[\)0-9]/?
                         ")"
                        :"("
           :"("
   }

```

If `n` equals zero, i.e., there are as many `(` as `)`, prints `(`. If `n` is different from zero, evaluates the last character (registered in `RT`). If it is a number or `)`, prints a `)`, otherwise, prints `(`.

# Answer
> 4 votes
# K (ngn/k), 30 bytes

```
{(^"(*+-/"?*|x)>~+/-/x=/:"()"}

```

Try it online!

Returns `0` for `"("` and `1` for `")"`.

* `~+/-/x=/:"()"` determine whether or not the input contains a balanced number of parenthesis, i.e. that the number of `"("`s minus the number of `")"`s is 0
* `(^"(*+-/"?*|x)` determine if the last character is one that should be followed by a `"("` (i.e. one of `"+-*/("`) or not
* `(...)>...` use `>` as material nonimplication (i.e. only return a truthy value if the left side is truthy and the right side isn't)

# Answer
> 3 votes
# JavaScript (ES6),  ~~52~~  51 bytes

Expects an array of characters. Returns `0` for `(`, or `1` for `)`.

```
a=>a.map(c=>q+=-(d=c>-1,C=c==')')|c<')',q=0)|q&&d|C

```

Try it online!

### Commented

```
a =>               // a[] = input array of characters
a.map(c =>         // for each character c in a[]:
  q +=             //   update q
    -(             //   which keeps track of the balance of parentheses
      d = c > -1,  //   d = digit flag
      C = c == ')' //   C = closing parenthesis flag
    )              //   decrement q if C is set
    | c < ')',     //   or increment it if c is '('
  q = 0            //   start with q = 0
) |                // end of map()
q &&               // return 1 if q is not 0 (unbalanced parentheses)
d                  // and the last character was either a digit
  | C              // or a closing parenthesis

```

# Answer
> 3 votes
# C# (8.0), ~~76~~ ~~68~~ 64 bytes

*-3 bytes thanks to ceilingcat
-1 byte thanks to Aaroneous Miller*

```
bool p(char[]i)=>i.Sum(x=>x<42?x*2-81:0)==0||i[^1]<48&i[^1]!=41;

```

Try it online!
Takes not-null (but it might be empty) array of characters and outputs `true` for `(` and `false` for `)`.

Ungolfed:

```
bool p(char[] input){
   int sum = input.Where(x=>x<42)  // take only brackets
       .Select(x=>x*2-81)          // replace '(' with -1 and ')' with 1
       .Sum();                     // sum them

   if(sum == 0)       // if sum is 0, brackets are balanced
       return true;
   // when left condition in || operator is true the right one isn't checked
   // this is beneficial for us because it prevents from taking last element
   // of empty array - empty input will always have balanced brackets

   char lastChar = i[^1];  // takes last character (this notation requires C# 8.0)

   return            // return true (opening bracket) IF:
      lastChar < 48  // last char is '/','*','-','+','(' or ')'
      &&             // AND
      lastChar != 41;// last char isn't ')'
}

```

# Answer
> 3 votes
# Zsh, 39 bytes

Exits truthy if a `(` should be inserted, falsy if a `)` should be inserted.

```
eval ${(s..)1//[^()]/;}||${(M)1%[0-9)]}

```

Try it online!

The `eval` handles the matching (getting rid of non-`()` characters, and spawning nested subshells with spaces and `;`s to prevent `()()` or `(( ))` from erroring).

The `${(M)1%[0-9)]}` simply tries to run the last character of the input as a program if it is in `0123456789)`, failing. `||` brings the whole logic together.

# Answer
> 3 votes
# TI-Basic, 71 bytes

```
Prompt Str1
For(I,1,length(Str1
sub(Str1,I,1→Str2
O+(Ans="(→O
C+(Str2=")→C
End
0
If O≠C
not(inString("+-*/(",sub(Str1,length(Str1),1
Ans

```

Output is stored in `Ans` and displayed. Outputs `0` for `(` and `1` for `)`.

# Answer
> 3 votes
# Jelly, ~~15~~ 14 bytes

```
ċⱮØ(Iɓ”)ØD;faƒ

```

Try it online!

*-1 because I actually looked at other solutions and remembered `ċ` exists*

Returns falsy (empty list) for open or truthy (nonempty list) for close. Took a hell of a lot of permuting to get here from `=€Ø(ISaṪe”)ṭØD¤Ɗ`.

```
        ØD;       Concatenate "0123456789" and
      ”)          a closing parenthesis.
           f      Keep only its elements which are also elements of
     ɓ      aƒ    the input reduced LtR by logical AND starting with:
ċⱮØ(              Count the opening and closing parentheses in the input,
    I             and subtract the opens from the closes.

```

# Answer
> 3 votes
# Haskell, 64 bytes

```
o i=elem(last i)"+-*/("||let[o,c]=[[1|c<-i,c==p]|p<-"()"]in o==c

```

Try it online!

# Answer
> 3 votes
## php 4 (83 chars)

Edited because the initial 67 chars answer was not a function, it was a single imperative line :

Using a traditional function allowing to call *f($input)*, so the answer is printed to stdout :

```
function f($a){$s=count_chars($a);echo$s[41]-$s[40]&&$a!=chop($a,')0..9')?')':'(';}

```

## php 7.4 (73 chars)

Using an arrow function allowing to call *$g($input)*, the answer is returned by *$g* :

```
$g=fn($a)=>$a!=chop($a,')0..9')&&($a=count_chars($a))[41]-$a[40]?')':'(';

```

# Answer
> 2 votes
# Vyxal, 23 bytes

```
k(↔k(øo[tkd\(+$ck($i|\(

```

Try it Online!

```
k(↔                     # When you remove all but `()` from the input
   k(øo                 # Then remove that until there is no change
       [                # Is there nothing left?
                     \( # If so, opening bracket
                    |   # Else...
        t               # Is the last character of the input...
              $c        # Contained in...
         kd\(+          # Digits + `(`?
                k($i    # Index that into `()`

```

# Answer
> 2 votes
# Retina 0.8.2, 39 bytes

```
(?>(\()|(?<-1>\))|.)*$(?<-1>(?<=[\d)]))

```

Try it online! Outputs `0` for `(` or `1` for `)`, but link is to test suite that maps the results for you. Explanation:

```
(?>(\()|(?<-1>\))|.)*$

```

Atomically count the `(`s and `)`s. (It needs to be atomic otherwise the `.` messes up the count of `)`s, but it's still golfier than `[^()]`.)

```
(?<-1>(?<=[\d)]))

```

Test whether there is an unclosed `(` and the last character is a digit or a `)`.

# Answer
> 2 votes
# Charcoal, 18 bytes

```
∨⁼№θ(№θ)№(*+-/§θ±¹

```

Try it online! Link is to verbose version of code. Outputs `-` for `(`, nothing for `)`. Pretty output can be obtained by prefixing `§)(` (equivalent to `AtIndex(")(", ...)`. Explanation: Port of @wasif's Python answer.

```
  №                 Count of
    (               Literal `(`
   θ                In input string
 ⁼                  Is equal to
     №              Count of
       )            Literal `)`
      θ             In input string
∨                   Logical Or
        №           Count of
              §θ±¹  Last character of input string
         (*+-/      In literal `(*+-/`
                    Implicitly print

```

# Answer
> 2 votes
# Flex, ~~86~~ 85 bytes

```
%{
p;l;
%}
%%
[(] l=!++p;
[)] p-=l=1;
[0-9] l=1;
[-+*/] l=0;
\n putchar(!!p*l+40);
%%

```

To run this code, copy the above into a file named `calc.l` and run the following (on linux/bash):

```
flex calc.l
gcc lex.yy.c -o calc -lfl
for t in "" "(1+" "(1+(2/3" "(1+(2/3)" "(1+(2/3))-8" "(1+(2/3))-8*(" "(1+(2/3))-8*((5" "(1+(2/3))-8*((5)" "(1+(2/3))-8*((5))"; do
    echo -n "\"$t\" -> "
    echo $t | ./calc
    echo
done

```

and it will output either `(` or `)` to `stdout` for each test string.

# Answer
> 2 votes
# Ruby, ~~47~~ 43 bytes

```
->e{!!e[/[\d)]$/]&&e.count(?()>e.count(?))}

```

Try it online!

Outputs *True* for `)`, *False* for `(`.

* Thanks to @Dingus for the insights and 4 Bytes saved

To choose `)` two conditions must hold:

`!!e[/[\d)]$/]` \# match($ at the end) the set of characters \[numbers, ')'\].
And double negate it to transform *nil*(no match) to *false* else *true*

`e.count(?()>e.count(?))` \# open brackets can be equal if balanced, else more than closed ones in which case the second condition is met.

# Answer
> 2 votes
# Pip, 17 bytes

```
$>^pNa&`[\d)]$`Na

```

Takes the partial expression as a command-line argument. Outputs `0` for open parenthesis, `1` for close parenthesis. Attempt This Online!

Verify all test cases!

### Explanation

```
$>^pNa&`[\d)]$`Na
                   a is command-line arg; p is "()" (implicit)
  ^p               Split p into a list of two parenthesis characters
    Na             Get the count of each parenthesis in the argument
$>                 Fold on > (1 if there are more open than close parens, 0 otherwise)
                   (Because we "can expect the input to be typed on the calculator,"
                   there will never be more close than open parens)
      &            Logical AND
       `      `    The following regex:
        [\d)]       Either a digit or a close paren
             $      followed by end-of-string
               N   Count matches in
                a  The argument

```

Thus:

* If the parentheses are balanced, `$>` gives `0`, which short-circuits the AND and returns `0` (open paren)
* Otherwise:
    + If the argument ends with a digit or `)`, return `1` (close paren)
    + If it doesn't, return `0` (open paren)

To get `(` and `)` as output, wrap the whole thing in `(p` ... `)` for +3 bytes.

# Answer
> 2 votes
# PHP (8.0), 110 bytes

```
<?php
$a=$argv[1];
$b=ord($a[-1]??'');
die($b>=47||$b==41&&substr_count($a,'(')>substr_count($a,')')?')':'(');

```

Try it online!

Ungolfed:

```
<?php
$a = $argv[1];
// Get the binary value of the first byte of the last character
$lastCharAsciiCode = ord($a[-1] ?? '');
// If the last character in the string is either 0-9 (47-57) OR Closing parenthesis (41)
if ($lastCharAsciiCode >= 47 || $lastCharAsciiCode == 41) {
    // If we have more opening parenthesis than closing, return closing.
    if (substr_count($a,'(') > substr_count($a,')')) {
        die(')');
    }
}
// Return opening by default
die('(');

```

# Answer
> 2 votes
# Rust, ~~107~~ 104 bytes

```
|s:&str|(|(n,x)|n==0||x)(s.chars().fold((0,true),|v,c|(v.0+match c{'('=>1,')'=>-1,_=>0},c<'0'&&c!=')')))

```

Try it online!

`true` for `(` and `false` for `)`

## Ungolfed

```
|s: &str| {
    // Iterate over all chars, folding from left
    let (paren_counter, ends_with_op_or_open) = s.chars().fold(
        (0, true), // Initial value for fold
        |(n,_), character| (
            // Increment for opening braces and decrement for closing ones
            n + match character { '(' => 1, ')' => -1, _ => 0 },
            // true for +-*/( but not for 0123456789)
            character < '0' && character != ')'
        )
    );
    // Return true if parentheses are balanced or the string ends
    // with an operator or open parenthesis, false otherwise
    paren_counter == 0 || ends_with_op_or_open
}

```

# Answer
> 2 votes
# , 57 bytes

```
function(x)sum((x=="(")-(x==")"))&&grepl("[)0-9]",rev(x))

```

Try it online!

Input is an array of characters; outputs `TRUE` if next parenthesis is close (`)`), `FALSE` otherwise.

# Answer
> 2 votes
# Javascript, 90 chars

```
s=>s.replace(/.*?([\d)])?$/,(m,c)=>")("[s.replace(/[()]/g,m=>t+=m=='('||-1,t=0),+!(t&&c)])

```

## Test:

```
f=s=>s.replace(/.*?([\d)])?$/,(m,c)=>")("[s.replace(/[()]/g,m=>t+=m=='('||-1,t=0),+!(t&&c)])

console.log(`
""                  -> "("
"(1+"               -> "("
"(1+(2/3"           -> ")"
"(1+(2/3)"          -> ")"
"(1+(2/3))-8"       -> "("
"(1+(2/3))-8*("     -> "("
"(1+(2/3))-8*((5"   -> ")"
"(1+(2/3))-8*((5)"  -> ")"
"(1+(2/3))-8*((5))" -> "("
`.split`
`.filter(x=>x).map(x=>x.match(/"(.*)".*"(.)"/)).map(([,x,r])=>f(x)==r).every(x=>x))
```

# Answer
> 2 votes
# brainfuck, 73 bytes

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

```

Try it online!

Outputs truthy for `)` and falsy for `(`. Note that this will fail if there are 256 unmatched `(`.

Version which outputs '(' or ')' (not particularly golfed)

**Explanation:**

```
,[                                           ,]                               loop until end of input
  +>-->[+]+[->+[--->]<<<]                                                       paren depth calculation: (brute forced black magic)
                                                                                '(' => 1
                                                                                ')' => 255
                                                                                '0123456789+-*/' => 0
                         <[->>+<<]                                              accumulate paren depth counter
                                  >>>[->>-<<]                                   preserve a data cell uniquely identifying last character
                                               <[,>>]                         if depth counter is nonzero move to cell identifying last character
                                                     ->[+>[>]--<<<++<+]>.     character to final output calculation: (brute forced black magic)
                                                                                '+-*/(' or \0 => 0
                                                                                '0123456789)' => nonzero

```

# Answer
> 2 votes
# JavaScript (Node.js), 15 bytes

```
a=>eval(a+')m')

```

Try it online!

tsh claim that "My function return results via throwing an exception"

# Answer
> 1 votes
# MATLAB, 65 bytes

```
@(x)all([sum(x(x<42)*2-81),feval(@(a,b)a(end)~=b,[0,x],'/*-+(')])

```

Try it online! Anonymous function. Outputs logical 1 for `)` and logical 0 for `(`.
Monstrosity with `eval` is required to handle empty input. Without that case it reduces to:

```
@(x)all([sum(x(x<42)*2-81),x(end)~='/*-+('])

```

which is much easier to comprehend. Ungolfed:

```
@(x)all([                                    % all of the conditions must be met
         sum(x(x<42)*2-81)                   % brackets are unbalanced
                          ,                  % AND
                           x(end)~='/        % last character isn't / AND
                                     *-+('   % isn't * AND ... (so on)
                                          ])

```

Checking of bracket unbalance works by taking only brackets in input: `x(x<42)` and then with multiplication and subtraction transforming `(` into `-1` and `)` into `1`. Then sum of these is converted to logical during execution of `all` \- `0` stays logical `0` anything else becomes logical `1`.

Omitted in ungolfed version `eval` additionaly puts `0` before whole input so last character will always exist.

# Answer
> 1 votes
# Core Maude, 206 bytes

```
mod B is pr LIST{Int}. ops b p : Nat ~> Nat . var A : Nat . var X Y Z :[Nat]. eq
b(nil)= 0 . eq b(X A)= 0 ^((~ A & 16)*(A xor 41)+ 0 ^ p(X A)). eq p(nil)=
0 . eq p(A X)= 0 ^(A & 22)* -1 ^(A & 1)+ p(X). endm

```

The result is obtained by reducing the `b` function with the input string given as a list of ASCII code points. The output will be `0` for open bracket and `1` for close bracket.

### Example Session

```
Maude> --- "" -> "("
> red b(nil) .
result Zero: 0
Maude> --- "(1+" -> "("
> red b(40 49 43) .
result Zero: 0
Maude> --- "(1+(2/3" -> ")"
> red b(40 49 43 40 50 47 51) .
result NzNat: 1
Maude> --- "(1+(2/3)" -> ")"
> red b(40 49 43 40 50 47 51 41) .
result NzNat: 1
Maude> --- "(1+(2/3))-8" -> "("
> red b(40 49 43 40 50 47 51 41 41 45 56) .
result Zero: 0
Maude> --- "(1+(2/3))-8*(" -> "("
> red b(40 49 43 40 50 47 51 41 41 45 56 42 40) .
result Zero: 0
Maude> --- "(1+(2/3))-8*((5" -> ")"
> red b(40 49 43 40 50 47 51 41 41 45 56 42 40 40 53) .
result NzNat: 1
Maude> --- "(1+(2/3))-8*((5)" -> ")"
> red b(40 49 43 40 50 47 51 41 41 45 56 42 40 40 53 41) .
result NzNat: 1
Maude> --- "(1+(2/3))-8*((5))" -> "("
> red b(40 49 43 40 50 47 51 41 41 45 56 42 40 40 53 41 41) .
result Zero: 0

```

### Ungolfed

```
mod B is
    pr LIST{Int} .

    ops b p : Nat ~> Nat .

    var A : Nat .
    var X Y Z : [Nat] .

    eq b(nil) = 0 .
    eq b(X A) = 0 ^ ((~ A & 16) * (A xor 41) + 0 ^ p(X A)) .

    eq p(nil) = 0 .
    eq p(A X) = 0 ^ (A & 22) * -1 ^ (A & 1) + p(X) .
endm

```

I hope it's not too cheesy to accept input as ASCII code points. Maude *has* a string module, but it's pretty weak and kind of verbose.

# Answer
> 1 votes
# Ly, 50 bytes

```
is<l>0sp["("=l+f")"=fp-sp]<")"=!f'0Lfp*l!+!!")"f-o

```

Try it online!

The algorithm for this one is:

* read in the input, store the last character in a separate stack
* run through all the chars, track `(` vs `)` balance in a saved cell
* test, `last="("` and `last<"0"`
* combine those three tests (paren balance is the 3rd one) to pick output

There's a caveat though. I don't think `Ly` can handle null character (as opposed to numeric) input. So it doesn't handle the first test case, which is a null string.

Here's the sausage making...

First part, get input and setup for run

```
i        - read the input onto the stack as codepoints
 s       - save the last char in the backup cell
  <l>    - switch stacks, load backup cell, switch back to original stack
     0sp - set the backup cell to "0", then delete 0 from stack

```

Count the `(` vs `)` chars, keeping a summary count of the balance

```
[               p] - process one char per iteration, until stack is empty
 "("=              - compare top of stack to "("
     l+            - load balance summary, increments on match
       f           - flip the current character to the top
        ")"=       - compare top of stack to ")"
            fp     - flip current char to the top, delete it
              -    - decrement balance summary if char was ")"
               s   - save balance summary to backup cell

```

Third, test the last character of the input.

```
<            - switch to the stack where we stashed the last char
 ")"=        - compare to ")"
     !       - negate result, we want "not equal"
      f      - pull the character to the top of the stack
       '0L   - test if less than character codepoint for "0"
          fp - pull the char to the top, then delete it

```

Fourth, combine the tests to get an output choice

```
*            - compute "and" of the last two tests
 l!          - load balance summary, negate
   +         - compute "or" of that and the previous test combo
    !!       - convert anything ">0" to "1" via double negate
      ")"f   - add ")" to stack, pull tests results to top
          -  - subtract to change char to "(" if called for
           o - output top of stack as a character

```

# Answer
> 1 votes
# Python3, 69 bytes

```
lambda d:[')','('][len(set(map(d.count,'()')))<2 or d[-1] in '+-*/(']

```

---
Tags: code-golf, string, decision-problem, parsing, balanced-string
---


# Question
Title: Cops and Robbers: Redacted Primality (Cops' Thread)
This challenge was originally sandboxed by Magic Octopus Urn; I adopted and posted it with his permission.

*This is the cops' thread. The robbers' thread is here.*

## The challenge

* **Step One:** Write a piece of code (function or full program) which checks for primality.
* **Step Two:** Remove pieces of your code by replacing characters with the symbol .
* **Step Three:** Post the redacted code on the cops thread.
* **Step Four:** Wait for your code to be cracked and try to crack other's code.

For example, the Groovy code `{it.isPrime()}` could become `{██.is█████()}`. (This one would be stupidly easy to crack; also, I know, `.isPrime()` is not a Groovy method.)

---

## Scoring

You must include your program's score in its submission. The score is defined as the ratio of redacted characters to characters. So if your program had 20 characters and 5 were redacted, your score would be 0.25. The Groovy code above would have a score of 0.5.

---

## Rules

* Your program only needs to handle *positive integers.* It should output a truthy value if the number is prime and a falsy value otherwise. Please specify in your answer what it outputs.
* Your code may not contain any comments or unnecessary whitespace.
* No hashing or cryptographic obfuscation.
* Your code may be no more than 50% redacted (at least 1/2 the characters must be shown). This means that the *highest* possible score is 0.5.
* If your answer is not cracked within a week you may mark it safe and edit in the intended crack.

---

## Winning

The winner will be the lowest-scoring uncracked answer within two weeks of posting. In the case of a tie, whichever has the most votes will win. This thread is always open to more submissions, but the winner chosen after two weeks will be permanent.

# Answer
> 3 votes
# Functoid, score = 14 / 223 ≈ 0.062780 \[safe\]

```
Y(yG(BK██)(B(S(BS(C(BC(C(BB(B(v
S(CB█)(█C█B>vK  BSBB())█K(BS(S?
>(KZ)(C(C(Bv>██        >   v██<
█)Sg3I)$; @>B(BS(b(C(BBI)Iv>(█g
())I)))I)IBB(C(b(CB(C())))<v)█C
I))I))0)))(C(BC(B(BB)(C(BBv>)))
]I))))I))>    >)█   $;@   >I)(B

```

Takes input as command-line argument and outputs `True` (prime) or `False`, try it online!

**Hint (added 4 days after posting):**

> The first and 4th  are a red herring: The intended (and most likely *every*) solution's IP will follow the first line and reach the `?` character.

### Solution

```
Y(yG(BKL2)(B(S(BS(C(BC(C(BB(B(v
S(CBO)( C B>vK  BSBB())OK(BS(S?
>(KZ)(C(C(Bv>O)        >   vY <
^)Sg3I)$; @>B(BS(b(C(BBI)Iv>(yg
())I)))I)IBB(C(b(CB(C())))<v)-C
I))I))0)))(C(BC(B(BB)(C(BBv>)))
]I))))I))>    >)2   $;@   >I)(B

```

Try it online!

### Explanation

Due to the randomness that comes from `?` it's not possible to flatten the program. Here's the flat program with a question mark where a random expression will be:

```
Y(yG(BKL2)(B(S(BS(C(BC(C(BB(B(?(yg(KZ)(C(C(BB(BS(b(C(BBI)I))))(C(BC(b(C(BBI)I)))I))(C-))))I))I))0)))(C(BC(B(BB)(C(BBI)(B]I))))I)))2$;@

```

Full program:

```
Y{trial_division}      --  fix-point of {trial_division}
                 2     --  apply 2 (begin division with 2)
                  $    --  apply argument (work with the supplied input)
                   ;   --  print result as boolean
                    @  --  terminate program

```

The `{trial_division}`:

```
y                         -- recursive function with two arguments x,y
 G                        -- | base predicate: x >= y
  (BKL2)                  -- | base function:  BKL2 x y
                             |  ->             K(L2) x y
                             |  ->             L2 y
                             |  ->             2 <= y
        {recursive_call}  -- | recursive call

```

`{recursive_call}`, taking arguments `f` (self-reference), `x` and `y` (note `0` is the same as `False`)

```
  B (S(BS(C(BC(C(BB(B{divides}I))I))0))) (C(BC(B(BB)(C(BBI)(B]I))))I) f x y
->       (C(BC(C(BB(B{divides}I))I))0) x y (BC(B(BB)(C(BBI)(B]I)))) f I x y)
->       (C(BC(C(BB(B{divides}I))I))0) x y (BC(B(BB)(C(BBI)(B]I)))) f I x y)
->            (C(BB(B{divides}I))I) x y 0  (BC(B(BB)(C(BBI)(B]I)))) f I x y)
->            (C(BB(B{divides}I))I) x y 0  (   B(BB)(C(BBI)(B]I))   f x I y)
->                   {divides}      x y 0  (         C(BBI)(B]I)    f x y  )
->              if x `divides` y then 0 else         C(BBI)(B]I)    f x y
->                                                    f (B]I x)  y
->                                                    f (] x) y
->                                                    f (x+1) y

```

`{divides}` is `?(yg(KZ)(C(C(BB(BS(b(C(BBI)I))))(C(BC(b(C(BBI)I)))I))(C-)))` where `?` is randomly chosen (depending on the random direction) from:

* `Y`
* `S(CBO)(CBO)`
* `S(SB(KO))(BBSBKO)`

These are all equivalent to each other, so `{divides}` becomes the fix-point of:

```
y                       -- recursive function with two arguments x,y
 g                      -- | base predicate: x > y
  (KZ)                  -- | base function:  KZ x y
                        -- |  ->              0 == y
      {recursive_call}  -- | recursive call

```

`{recursive_call}` is a pretty obfuscated expression that basically just does `f x (y-x)`

# Answer
> 5 votes
## 8086 DOS COM, 87 bytes, score 19/87 ~= 0.2183

Cracked by NieDzejkob

```
1└╣██1█╛ü ¼<█t<< u≈¼<█t█,0|/<██+ô≈ßô☺├δδâ√█|█╞█S█Y╣██9┘t█ë╪1╥≈±○╥t█Aδ∩╞█S█N┤█║S█═!├A
$

```

This is a COM program; expects number as a command line argument, outputs Y or N. Limit: 65535 because 16 bit processor (sizeof(int) would be 2). Newline is 0x0D 0x0A on this platform. Yes you count 20 █ instead of 19 █. One of them's a real █ and has not been substituted. Muhahaha.

The space in position 10 is actually a NUL byte. The symbol for NUL is the same as space in the old VGA font.

# Answer
> 5 votes
# Swift 4, score 26 / 170 ≈ 0.153, safe

```
func p(n:Int)->Bool{func █(_ █:Int,_ █:Int)->Int{var h=(1...l).map{$0██m██
while(m=h.count,m██).1{h=[Int](h[█...])};return m}
return █>██&(█.███).index█j█n██0)>=█0}█=██l}

```

Try it online!

## Intended Crack

```
func p(n:Int)->Bool{func j(_ l:Int,_ k:Int)->Int{var h=(1...l).map{$0},m=l
while(m=h.count,m>k).1{h=[Int](h[k...])};return m}
return n>1&&(2..<n).index{j(n,$0)>=$0}==nil}

```

## Ungolfed

```
func p(n:Int)->Bool{
  func j(_ l:Int,_ k:Int)->Int{    // Modulus function (l mod k)
    var h=(1...l).map{$0},m=l      //  Create an array h of size l
    while(m=h.count,m>k).1{        //  While h has more than k elements:
      h=[Int](h[k...])             //   Remove k elements from h
    }
    return m                       //  Return the length of h (equal to k if l divides k)
  }
  return n>1&&                     // Test if n > 1
  (2..<n).index{j(n, $0)>=$0}==nil //  and no number from 2 to n-1 divides n
}

```

# Answer
> 4 votes
# brainfuck, 37/540 bytes (score: 0.06851) (Cracked by Nitrodon)

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

```

Try it online!

Prints "prime" if prime, "not prime" if composite. Technically works for arbitrary integers but times out on TIO for numbers above 6000

# Answer
> 3 votes
# Python 3, 388 bytes, .155, Cracked

Last-minute crack. Yes, this is the Miller-Rabin test.

I suppose probabilistic tests are allowed, uncertainty 2^-100

Well, a great hint in the previous sentence though

Made return value 0 as COMPOSITE and 1 as PROBABLY PRIME

\*368 \> 388 : Fixed the problem when z\<4

```
import ██████
def f(z):
 if z<4:return z>>1
 d,s,n,e,c=██z,0,z,0,50
 while not ██1:d//=2;s+=1
 while n>0:n//=2;e+=1
 ███████████()
 while c>0:
  a=0
  while a<2or a>z-█:
   a,b=0,e
   while b>0:a=a*2+██████████████(0,1);b-=█
  x,r=███(█,█,z),██s
  if ██x and x!=██z:
   while r>0:
    x,r=███(█,█,z),██r
    if not ██x:return 0
    elif x==██z:break
   else:return 0
  c-=█
 else:return 1

```

Solution:

```
import random
def f(z):
 if z<4:return z>>1
 d,s,n,e,c=~-z,0,z,0,50
 while not d&1:d//=2;s+=1
 while n>0:n//=2;e+=1
 random.seed()
 while c>0:
  a=0
  while a<2or a>z-1:
   a,b=0,e
   while b>0:a=a*2+random.randint(0,1);b-=1
  x,r=pow(a,d,z),~-s
  if ~-x and x!=~-z:
   while r>0:
    x,r=pow(x,2,z),~-r
    if not ~-x:return 0
    elif x==~-z:break
   else:return 0
  c-=1
 else:return 1

```

# Answer
> 3 votes
# Mathematica, 97 bytes, score 0.2989690722 (Cracked)

```
f[x_]:=(██ToString███████████████;StringMatchQ[████Infinity,RegularExpression@"█\█\█{█\█+, ███"])

```

Strings! Regex! Primes?

There *is* such a thing as a primality checking regex, but that's not whats happening here.

This has been cracked, but the way I intended was quite different, so I won't reveal the intended solution yet.

# Answer
> 3 votes
# Jelly, score 0.(142857) (cracked)

```
25██26█966836897364918299█0█1█65849159233270█02█837903312854349029387313█ị██v

```

Try it online!

Repost of my other answer, this time with a few more bytes revealed to avoid unintended cheats.

# Answer
> 3 votes
# 095, score 0.20512820512 \[Safe\]

```
1id#█#=(DD#█#█{d_█%(█D0█]D}██s]D1.=[1s]

```

Prints 1 if prime, 0 if composite

Solution:

```
1id#2#=(DD#2#-{d_.%(rD0R]D}drs]D1.=[1s]

```

# Answer
> 3 votes
# Octave, Score: 0.15 (86 bytes)

I revealed several more characters. I thought the winning criterion was *highest* score, not *lowest*.

```
@(x)eval([(str2num(cell2mat([cellstr(reshape('0█1███1█0█0█00',████))])')█'█')','(x)'])

```

Try it online!

Good luck =)

# Answer
> 2 votes
# Node JavaScript, score: 0.4

Here's where it works. Full program that takes input from first command line argument, and outputs to stdout.

Hopefully, a not-so-difficult solution to start this off.

Using this snippet to calculate score.

```
require███████████2<<2██>n█████rin█(b████████x)█████(9211█6830)██(a,c)=>a[c[0]██████████(c)]███████);d=███+n;q=████27775██9564,[502█59,█6])[█]);a=██q>0████r(n=q█a█&█-q-██)a██n%q?██0██(137152█8270,22288)(a)

```

# Answer
> 2 votes
# Japt, 19 bytes, 0.315789... score, Safe

I don't know if I obscured more of this than I needed to, costing myself a better score.

```
█h8575¥█
█UâÊ█Ê█ █2

```

`View solution` (Explanation coming soon)

# Answer
> 2 votes
# Jelly, score 0.(142857)

```
25██26█9668368973649182992051██5849159233270202█837903312854349029387313█████

```

Try it online!

Takes a command-line argument.

False = `0`
True = `1`

# Answer
> 2 votes
# JavaScript, 103 bytes, score 0.1923

`x=>{if(x<4)return(!0);for(y=x>>>Math.log10(p=████;--y-1;(p=x/y%1)████if(██&&(███))break████return(███)}`

Returns a boolean.

Unintended crack

# Answer
> 2 votes
# Brain-Flak, Score: 35/134 = 0.2612 (cracked!)

`(({████){██[████)█>(({}))<>}<>{}███{}((██({}))█████{}]██)({}(<>))<>{(({})){({}[()])<>}{}}{}<>([{}()]{})██[██()██(()█[()]██{}██}{}<>{})`

Returns 1 for prime, 0 for composite.

This is a very hard language to try this challenge in, as the formatting is so restricted that it takes effort not to make it obvious what the missing character is.

This is a very hard language to solve this challenge in, as it is ridiculously hard to read.

# Answer
> 2 votes
## Javascript, score 0.1894093686354379

```
let t=[2,3,3,3,3,3,3,5,7,5,7,5,7,7,11,12,13,11,13,13,1,2,17,13,2,3,17,19,23,29,19,19,41,23,23,29,23,"","",29,7,31,31,524,31,37,33,34,41]; function r(a, b) {█████████████████████████████████████████████████████████████};function l(t){let a=0;let b=[];while(true){b.push(t[a]);█████████████;if(!t[a]){return█████};function p(v) {let i=0;let a=r(2,v██);for (i in a){if(v%(█████████a█i██)==0){return false;}};return true;};function f(v){if(l(t).indexOf(v)!=-1){return true;}else{return p(v)};};

```

Good luck. :p

call f with the prime you want to check.

# Answer
> 2 votes
# \>\<\>, score 0.096, cracked by Jo King

```
:1@v>~~:?1n;█$-1<█?=2:}*{█@:$@:

```

Intended crack:

> ```
> :1@v>~~:?1n;
> $-1<^?=2:}*{%@:$@:
> ```

# Answer
> 2 votes
# Java 1.4+, 24/145 (0.16551724137)

```
class X{public static void main(String[]args){System.out.println(new String(████████[Integer.parseInt(args[0])]).matches("█████████████")?███);}}

```

Try it online!

---

Weirdest way I've seen to prime check in Java by far lol.

# Answer
> 2 votes
# C, 34/76 = 0.447368, Safe

```
int p(int n){int r███████2;██r███r++)███+███n;████&███r));return███████n██;}

```

Having this many blanks means that I will be much more likely to get an unintended crack than the intended one.

### Solution:

> `int p(int n){int r=1,e=n%2;for(;(r++)*(r++)<n;e=e&&(n%r));return e?n>1:n<3;}`

explanation:

> `e` holds a boolean value of whether or not the number is not prime (with a few special case exceptions). `r` iterates through the odd numbers less than or equal to the square root of `n`. `return e?n>1:n<3;` handles the special cases when `n` is `1` or `2`.

# Answer
> 2 votes
# , score: 4/22 = .1818..., cracked by Dennis

```
███“;;█»VOḣ2S⁵++3Ọ;”Pv

```

~~This may end up with an unintended crack, we'll have to see.~~ It did.

Dennis' solutions is

```
ÆPø“;;“»VOḣ2S⁵++3Ọ;”Pv

```

Try it online!

I will leave my solution hidden for someone to crack. My hint to Dennis on his robber submission was the word "zoo".

# Answer
> 1 votes
# Pyth, score: ~0.(461538) (13 bytes) (Cracked)

```
█]█Q ██Q{█M█P

```

Try to crack it here!

# Answer
> 1 votes
# Pyt, score: 0.288288... \[Safe\]

```
Đ2⇹█ŘĐĐŁ███⇹ʀĐ↔Đ5Ș↔⇹██=█ŕĐ↔Đ5Ș↔Đř█⇹█████↔Đ4Ș5Ș⇹██⇹3Ș°04Ș↔█3ȘĐŁ█3Ș05Ș↔█⇹04Ș0↔⇹██=█ŕ↔ŕĐĐŁ██↔██↔ŕŕŕŕ█↔████↔ŕŕŕ██¬¬

```

Outputs "True" if prime, "False" if not

Forgot to mention that it is a probabilistic test.

Solution:

```
Đ2⇹⁻ŘĐĐŁ₂`⁻⇹ʀĐ↔Đ5Ș↔⇹Ǥ1=?ŕĐ↔Đ5Ș↔Đř²⇹%∈2*⁻↔Đ4Ș5Ș⇹⁻₂⇹3Ș°04Ș↔+3ȘĐŁ⁺3Ș05Ș↔+⇹04Ș0↔⇹%+=?ŕ↔ŕĐĐŁ⁺⁺↔ł:↔ŕŕŕŕ;↔⁺⁻±?↔ŕŕŕ:;¬¬

```

This implements the Solovay-Strassen primality test.

Try it online here!

# Answer
> 1 votes
# C, 66 bytes, 29 redacted, score 0.439

```
i;p(n){█████2███████ 0███████2;███;███)if(████)return 0;return 1;}

```

Just a simple C submission; I'll see how long this one takes before I post a really evil one.

# Answer
> 1 votes
## sh + coreutils, score 19 / 143 ~= 0.1328

cracked

```
e█ec█s█ █c "██████WyAkKHNoIC1jICJg█WNobyBabUZqZEc5eWZIUnlJQ2█2SnlBblhHNG5m██JoYVd3Z0t6SjhkMk1nTFhjSyB8YmFzZTY0IC1kYCIpIC1lcSAxIF0K█b█se6███d`"

```

TIO

# Answer
> 1 votes
# Brain-Flak, score 29 / 140 = 0.207

`({}██()██<>){██({}[()])██{}{}███({<({}[()])><>({})<>}{}██████{}██){(({})){({}[()])<>}{}}<>([{}()]{}<>{})<>}(<>██{}({}████)((){[()]██{}██}{})`

Try it online!

Outputs 1 for prime and 0 for non-prime.

# Answer
> 1 votes
# Tampio (imperative), score: 24/51 = 0.5

```
Luku on alkuluku,jos ████████████e███████ on █████.

```

This is an obvious solution, I hope no one here understands Finnish.

# Answer
> 1 votes
# Tampio (imperative), score: 26/223 = 0.11659...

```
Luvun kokonaislukuarvot ovat riippuen siitä,onko se yksi,joko listan,jonka alkioita ovat yksi █████████████████████,alkiot tai █████ liitettynä sen alkutekijöihin.Luku on alkuluku,jos sen kokonaislukuarvojen summa on nolla.

```

# Answer
> 1 votes
# Python 3, score: 0.386363, cracked

```
p=lambda x,i=2:█████or(x%i and ████████)████

```

Going for the *really* low hanging fruit at first. I'll come up with a cheeky answer soon.

user71546 made it "work" with

```
p=lambda x,i=2:i>=x or(x%i and p(x,i+1))or 0

```

...but that was unintended. Original code was

```
p=lambda x,i=2:i>x/2or(x%i and p(x,i+1))or 0

```

Neither work for x\<2, turns out. Oops.

# Answer
> 1 votes
# Ruby, 27/73 = 0.369863

```
def p n;███████(██n.times████a[2..-1].map{|s|█.██n████s}██.█*█|██})█);end

```

This should be fun.

# Answer
> 0 votes
# JavaScript (ES7), 297 bytes, 103 redacted, .347

```
M=(N,X=N,F=(n,a=█████)=>a>1e-20?█████+F(n,█████████):1,G=(n,a=█████)=>a>1e-20?█████+G(n,███████):n==2?0:G(n-1),H=(n,a=█████)=>a>1e-20?█████-H(n,███████):0,I=n=>████████I(████),J=n=>I(n)*████+H(█████████-1),K=(n,l=n|0)=>(n-l>=.5)+l,L=(a,b)=>██████████(a)+█(b)████,Z=L(--N,N)██)=>L(Z,████M(N,X)██)██

```

My previous Python answer was too straightforward, so here's an evil one ;)

The logic behind is straightforward though.

# Answer
> 0 votes
# Python 3, 48 bytes, 24 redacted, .5

```
def p(x):
  return ███(██████████████████(█,██))

```

Just a simple answer, probably gonna be solved in under 24 hours.

---
Tags: code-challenge, primes, cops-and-robbers, obfuscation
---


title: Wash clothes as quickly as possible

text:
# Question
Title: Wash clothes as quickly as possible
It's laundry day, and you have lots of clothes that need to be washed. Wanting to have as much time left over for code golf as possible, you hope to optimize how quickly you wash and dry them all.

You have three types of appliances:

* Washing machines: Take dirty clothes and turn them into wet clothes
* Dryers: Take wet clothes and turn them into dry clothes
* Dishwashers: Take dirty and/or wet clothes and turn them into dry clothes

You'll be given a list of appliances, including a capacity (the number of items of clothing, as a nonnegative integer, that can be washed in it at once) and a run time (the time in minutes, as a nonnegative integer, that it takes to finish its job). Additionally, you'll be given a nonnegative integer describing how many items of clothing you have.

## Task

Given a list of appliances and a number of items of clothing, you'll return the minimum number of minutes it would take to wash and dry them all. You don't need to return the actual set of operations it would take to do so.

At any time, you can perform any of the following operations:

* Take up to \\$n\\$ dirty clothes, and put them in an available washing machine (where \\$n\\$ is less than or equal to its capacity)
* Take up to \\$n\\$ wet clothes, and put them in an available dryer (where \\$n\\$ is less than or equal to its capacity)
* Take up to \\$n\\$ dirty or wet clothes, or some combination, and put them in an available dishwasher (where \\$n\\$ is less than or equal to its capacity)
* If it has been \\$x\\$ minutes since a washing machine was loaded, the clothes in it can be removed. They are now wet, and the washing machine is now available again.
* If it has been \\$x\\$ minutes since a dryer or dishwasher was loaded, the clothes in it can be removed. They are now dry, and the appliance is now available again. (Don't worry, you clean the lint trap like a responsible code golfer)

Clothes are "fungible", so you can keep track of all of the clothes not in a running appliance using three nonnegative integers (one for dirty, one for wet, and one for dry).

## Example

Let's say you have 120 articles of clothing, and the following appliances:

* A washing machine, with a capacity of 10, that takes 40 minutes
* A washing machine, with a capacity of 40, that takes 180 minutes
* A dryer, with a capacity of 40, that takes 120 minutes
* Two dishwashers, each with a capacity of 15, which take 100 minutes

An example solution would be (red/dark red indicating dirty clothes in, blue indicating wet clothes in, purple indicating a mix, units of 20 minutes):

This takes a total of 300 minutes. The second pair of dishwasher cycles contain a total of 10 dirty clothes, and 20 wet clothes, and the final two dishwasher cycles aren't completely full. To optimize this any further we'd need to remove two dishwasher cycles and start the dryer earlier (or not at all), which would not result in all clothes being washed.

## Test cases

Formatted as `num_clothing, washing_machines, dryers, dishwashers`, with appliances formatted as `[capacity, mins_to_finish]`:

```
1, [], [], [[1, 10]]                            10
10, [], [], [[1, 10]]                           100
1, [[2, 2]], [[1, 4]], [[1, 10]]                6
2, [[2, 2]], [[1, 4]], [[1, 10]]                10
2, [[2, 2]], [[2, 4]], [[1, 10]]                6
16, [[2, 2]], [[1, 4]], [[1, 10]]               50
16, [[2, 2]], [[1, 4]], [[1, 10], [10, 20]]     20
10, [[1, 10]], [], [[3, 10]]                    40
4, [[1, 1]], [[1, 2], [2, 4]], []               7
4, [[1, 1], [1, 2]], [[1, 2], [2, 4]], []       6
6, [[1, 1], [1, 2]], [[1, 2], [2, 4]], [[1, 4]] 4

```

*I'm not entirely sure these are correct; my reference implementation is buggy.*

## Other

This is , so shortest answer in bytes (per language) wins.

# Answer
> 3 votes
# Python3, 1091 bytes:

```
import itertools as I
g=lambda x:[[a,[0,b]]for a,b in x]
E=enumerate
def p(m,o):
 k=0
 for i,a in E(m):
  if a[1][1]==1:k+=a[1][0];m[i][1][1]=o[i][1];m[i][1][0]=0
  elif a[1][0]:m[i][1][1]-=1
 return k
C=lambda x:eval(str(x))
def P(d):
 a,b=zip(*[(a[0],range(0,[0,a[0]][a[1][0]==0]+1))for i,a in E(d)])
 return[[a,i]for i in I.product(*b)]
def U(b,d):
 for x,y in P(d):
  if(s:=sum(y))<=b:
   D=C(d)
   for i,(j,k)in E(zip(x,y)):D[i][1][0]+=k
   yield b-s,D
def K(N,r,Q,s=[]):
 if[]==Q:yield(N,r,s);return
 if Q[0][1]:
  if Q[0][0]in[0,2]:
   for a,b in U([N,0,r][Q[0][0]],Q[0][1]):yield from K([a,0,N][Q[0][0]],[r,0,a][Q[0][0]],Q[1:],s+[b])
  else:
   for x in[{0:N,1:r},{1:r,0:N}]:
    b=Q[0][1]
    for i in[*x]:
     for a,b in U(x[i],b):x[i]=a;yield from K(x[0],x[1],Q[1:],s+[b])
 else:yield from K(N,r,Q[1:],s+[Q[0][1]])
def f(n,w,d,s):
 q=[(n,*map(g,[w,d,s]),0,0,0)];O=[]
 while q:
  N,*U,r,c,t=q.pop(0)
  W,D,S=map(C,U)
  if c==n:return t-1
  r+=p(W,w);c+=p(D,d)+p(S,s)
  for _n,_r,[_w,_s,_d]in K(N,r,[(0,W),(1,S),(2,D)]):
   if(M:=(_n,_w,_d,_s,_r,c,t+1)) not in O:
    q+=[M];O+=[M]

```

Try it online!

Very brute force solution and as such, it times out on the larger test cases. I will come back to those later.

---
Tags: code-golf, optimization
---