# Verb arities in J trains

## Background

J has trains similar to APL's. Given a sequence of verbs (functions), three rightmost verbs are grouped to form a derived verb (a fork) recursively, until one or two verbs remain. If the sequence has odd length, the entire train is a chain of forks. Otherwise, two verbs remain at the end, forming a hook.

    (F G H J K) x             5-train called monadically
->  (F G (H J K)) x
->  (F x) G ((H x) J (K x))   Function arities: 1, 2, 1, 2, 1

x (F G H J K) y                 5-train called dyadically
->  x (F G (H J K)) y
->  (x F y) G ((x H y) J (x K y))   Function arities: 2, 2, 2, 2, 2

(F G H J K L) x                 6-train called monadically
->  (F (G H (J K L))) x
->  x F ((G x) H ((J x) K (L x)))   Function arities: 2, 1, 2, 1, 2, 1

x (F G H J K L) y               6-train called dyadically
->  x (F (G H (J K L))) y
->  x F ((G y) H ((J y) K (L y)))   Function arities: 2, 1, 2, 1, 2, 1


You don't need to fully understand J trains to solve this challenge. The pattern is pretty simple:

• If the train length is even, the pattern is [2, 1, 2, 1, ..., 2, 1] regardless of the train's arity.
• Otherwise (length is odd), if the train is called monadically, the pattern is [1, 2, 1, 2, ..., 2, 1]; if called dyadically, the pattern is all 2's.

## Challenge

Given a train's length and arity (monadic is 1, dyadic is 2), output the arities of each function in the train.

Standard rules apply. The shortest code in bytes wins.

## Test cases

length, arity -> answer
1,      1     -> [1]
1,      2     -> [2]
2,      1     -> [2, 1]
2,      2     -> [2, 1]
3,      1     -> [1, 2, 1]
3,      2     -> [2, 2, 2]
4,      1     -> [2, 1, 2, 1]
4,      2     -> [2, 1, 2, 1]
9,      1     -> [1, 2, 1, 2, 1, 2, 1, 2, 1]
9,      2     -> [2, 2, 2, 2, 2, 2, 2, 2, 2]
10,     1     -> [2, 1, 2, 1, 2, 1, 2, 1, 2, 1]
10,     2     -> [2, 1, 2, 1, 2, 1, 2, 1, 2, 1]

• May we output a list or string with any two distinct values? Nov 10, 2021 at 3:57
• @chunes No, here 1 and 2 have specific meaning, so you need to specifically output those numbers. Outputting a string like "2121" is fine though. Nov 10, 2021 at 4:05
• Nov 10, 2021 at 7:40

# Python 2, 28 bytes

lambda l,a:(l*[2,l%a+1])[l:]


Try it online!

### Python 2, 27 bytes

It saves one byte to output as a string.

lambda l,a:(l*21+l%a)[l:]


Try it online!

# HBL 0.1, 10 bytes

<(0.(*(1(+(%.,))2?).


Try it at HBL Online!

HBL uses a half-byte codepage. Each character above represents one hex digit, two characters per byte. Here's a hexdump of the raw binary file:

00000000: 3c0a c5c1 c4c8 abdd 29da                 <.......).


### Explanation

If we reverse the desired output, we can see some patterns emerge:

3 1  (1 2 1)
3 2  (2 2 2)
4 1  (1 2 1 2)
4 2  (1 2 1 2)
5 1  (1 2 1 2 1)
5 2  (2 2 2 2 2)

• The output is some two-element list repeated a number of times and trimmed to a length equal to the first argument.
• The second element of that list is always 2.
• The first element of that list is 2 if the arguments are, respectively, an odd number and 2; otherwise, the first element is 1.

This leads to our initial solution, given here in Thimble, HBL's "ungolfed mode":

'(reverse           ; Reverse of
(take arg1        ; The first (arg1) elements of
(repeat          ; Repeat the following list...
(cons           ;  Construct a list from the values...
(cond          ;   If...
(mul          ;    Multiply
(odd? arg1)  ;    parity of arg1
(dec arg2))  ;    by (arg2 - 1)
2             ;   ... is nonzero, then 2
1)            ;   else 1
2              ;  ... and 2
nil)           ;  prepended to the empty list
arg1)))         ; ... (arg1) times


Translating this solution into HBL gives <(0.(*(1(?(*(%.)(-,))21)2?). (14 bytes). To get to our 10-byte solution, observe that there's a nice relationship between our two arguments and the number we want in our list:

 arg1 % 2 | arg2 | num | arg1 % arg2
----------|------|-----|-------------
0        | 1    | 1   | 0
0        | 2    | 1   | 0
1        | 1    | 1   | 0
1        | 2    | 2   | 1


So instead of the conditional, all we need is (inc (mod arg1 arg2)).

'(reverse
(take arg1
(repeat
(cons
(inc
(mod arg1 arg2))
2
nil)
arg1)))


Replacing the builtins with their HBL equivalents and removing the opening and closing parentheses (implicit in HBL), this solution maps directly onto the HBL solution given above.

• Nice observation and explanation. Nov 10, 2021 at 22:27

# Jelly, 7 bytes

%‘;2ṁḷU


Try it online!

Thanks to Unrelated String for making this work! Port of dingledooper's answer.

%‘ṭ2ṁḷU # Dyadic link taking two arguments
ṁ   # Mold...
;2    # 2 appended to...
%       # The modulo of the two inputs
‘      # Plus 1
ṁ   # To length...
ḷ  # Left argument (length input)
U # Reversed


# 05AB1E, 10 bytes

%21+sиJs.$ Try it online! • Fails for (1,9) and all odd-length inputs in general. Nov 10, 2021 at 6:11 • @Bubbler fixed though it ended up becoming dingledooper port Nov 10, 2021 at 6:27 • иJ is the builtin ×. And here an alternative 9-byter: %T*12+²∍R Nov 10, 2021 at 11:09 • My alternative 9-byter can actually be a 7-byter like this: %>2«²∍R (port of the Jelly answer) Nov 10, 2021 at 20:24 # Factor + sequences.repeating, 50 bytes [ dupd mod 1 + '[ 2 _ ] over 2 * cycle swap tail ]  Try it online! This is a port of @dingledooper's excellent Python 2 answer. There is a locals version that is the same length: [| l a | 2 l a mod 1 + 2array l 2 * cycle l tail ]  Try it online! ## Explanation: It's a quotation (anonymous function) that takes the length and the arity (in that order) from the data stack as input and leaves a sequence on the data stack as output. Assuming 9 1 is on the data stack when this quotation is called... Snippet Comment Data stack (the bottom is the top) 9 <--- NOS (next on stack)1 <--- TOS (top of stack) dupd Duplicate NOS 991 mod NOS % TOS 90 1 Push 1 901 + NOS + TOS 91 '[ 2 _ ] Slot TOS into the _ 9[ 2 1 ] over Copy NOS to TOS 9[ 2 1 ]9 2 Push 2 9[ 2 1 ]92 * NOS * TOS 9[ 2 1 ]18 cycle Repeat NOS until length of TOS 9[ 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 ] swap Swap NOS and TOS [ 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 ]9 tail Take NOS from index at TOS [ 1 2 1 2 1 2 1 2 1 ] # Retina 0.8.2, 32 bytes \d+$*
r11
21
T1221,1.*
.+,



Try it online! Link includes test cases. Takes input in the order arity, length. Explanation:

\d+
\$*


Convert the length to unary, conveniently using 1s.

r11
21


Working right-to-left, change every other 1 to a 2.

T1221,1.*


If the arity is two and the length is odd, change all the 1s to 2s.

.+,



Delete the arity.

# Vyxal, 8 bytes

%21+S⁰*∷


Try it Online!

-1 thanks to emanresuA

Haha 05ab1e porting goes brrrr. When v2.6.0pre2 drops later this week, this'll be 7 bytes:

%21+⁰ẋ∷


## Explained (old)

%21+S⁰*⁰ȯ # Full program, takes arity, length
%         # Push length mod arity,
21+      # add 21 to that,
S     # and cast to string. (This value will be called x)
⁰    # Push the length,
*   # and repeat x that many times. (This value will be called y)
⁰  # Push the length again,
ȯ # and push y[length:]

• you ported me, and I ported dingledooper lol Nov 10, 2021 at 6:38
• -1 with the first half Nov 10, 2021 at 8:34

# Ruby, 25 bytes

->l,a{([2,l%a+1]*l)[l,l]}


Try it online!

Another port of @dingledooper's Python answer.

# J, 47 bytes

(".@,'~'''''}.~2&|)~'(',')',~,&'1&, :(,2&,)'&''


Try it online!

I would call this one a conscious un-golf, because ofc I could port dingledooper's Python answer to J for fewer bytes...

But it just didn't feel right for a J answer not to use J's train parsing code to compute the answer.

## the idea

First, we construct a verb 1&, :(,2&,) that prepends 1 to its argument (say a b c) when called with 1 argument:

1 a b c


but plops 2 in the middle when called with 2 args:

a b c 2 a b c


Next we duplicate that verb length times to form a train, and then invoke the train on the empty list ''. More precisely, we call:

train ''


if our arity is 1, and:

'' train ''


if our arity is 2.

With that setup, J's train execution will do the required computation for us.

# Jelly, 6 bytes

ḶU|%Ḃ‘


Try it online!

Like Dingledooper's answer, but a bit different.

ḶU       range [L-1..0]
|%     bitwise OR by L%A
(if L%A=0, this does nothing;
if L%A=1, it makes the whole range odd)
Ḃ‘   mod 2, add 1


# R, 38 bytes

Or R>=4.1, 31 bytes by replacing the word function with \.

function(l,a)tail(rep(2:(l%%a+1),l),l)


Try it online!

Based od @dingledooper's idea.

# C (gcc), 46 bytes (44 using puts)

i;f(l,a){for(i=l;i--;)printf(L"122"+i%2+l%a);}


Try it online!

• Based on @dingledooper answer

# MathGolf, 9 bytes

\%J+░*h½≥


Port of @dingledooper's Python answer.

Try it online.

Explanation:

\          # Swap the two (implicit) input-integers
%         # Modulo
J+       # Add 21
░      # Convert it to a string
*     # Repeat it the first (implicit) input-integer amount of times
h    # Push the length of this string (without popping)
½   # Halve it
≥  # Remove that many leading digits from the string
# (after which the entire stack is output implicitly as result)


# Charcoal, 12 bytes

Ｎθ↓Ｉ……⊕﹪θＮ³θ


Try it online! Link is to verbose version of code. Explanation:

Ｎθ              Input the length as an integer
…          Range from
θ       Input length
﹪        Reduced modulo
Ｎ      Arity as an integer
⊕         Incremented
³     Until 3 (exclusive)
…           Cycled to length
θ    Input length
Ｉ            Cast to string
↓             Output right-to-left


Instead of ↓, either ← or ⮌ can be used for vertical output.

# Rust, 61 bytes

|l,a|->Vec<_>{(0..l).rev().map(move|x|(x|l%a)%2+1).collect()}


Try it online!

Port of @Lynn's Jelly answer.

Generates range l-1 .. 0, bitwise ORs each item with l modulo a, then modulos the result with 2 and adds 1

Range in rust ((start..stop)) must be ascending, as it returns an empty iterator if start >= stop, so we have to .rev() the range to reverse it before mapping. Thankfully though the stop of a range is exclusive, so (0..l) generates range 0 to l-1 inclusive.