# Lumberjaxe Code Golf

Tom the lumberjack is going to do his daily routine: chop trees. After all, it's his job to do so. His boss has ordered him to chop trees in a straight line marked with a special tape to identify them, so he knows which trees he is going to have to chop. However, Tom quickly realizes he has a problem. His axe will only chop so much wood before breaking, and he forgot to bring a spare with him. Plus, the trees are different sizes. A small tree, marked with an i, will take 2 swings of the axe to chop, and a large tree, marked with an | will take 4 swings. Can Tom chop all of the assigned trees?

The Objective

Given two inputs, a string that determines the sequence of small and large trees and an integer that determines the durability of the axe, create a program that determines not only if Tom's axe will break or not, but also determine how many of each tree type he chopped down. It's , so the shortest code in bytes wins!

Example

Input 1 example:i||iii| This input string determines the sequence of trees.

Input 2 example:50 This input integer determines the durability of the axe.

The outputs for this particular example will be a boolean and a string as follows(True means Tom's axe broke): False 4 small, 3 big

• How flexible is the output format? Would [ false, [ 4, 3 ] ] work as well? – Arnauld Jul 5 at 23:16
• Can you give more examples with edge cases, e.g. 20 durability? Should the axe break on the last swing of i||iii| or not? – xash Jul 5 at 23:44
• You should wait at least 1 week before accepting an answer. And since this is a code-golf challenge, you should accept the shortest one. (PS: On CGCC, it's also perfectly fine to never accept any answer.) – Arnauld Jul 6 at 0:23
• Some more examples will make for a better challenge. – Abigail Jul 6 at 20:24
• @NipDip: "Sure, as long as I can read the input its fair game." So, using 2 for i and 4 for | in the input is OK? – Shaggy Jul 6 at 20:56

# 05AB1E, 20 bytes

-5 bytes thanks to Kevin Cruijssen.

ηʒÇ3%·ÌO@}θD¹Ês{γ€g‚


Try it online!

## Explanation

η                    Prefixes of the input. ["i", "i|", "i||", "i||i", "i||ii", "i||iii", "i||iii|"]
ʒ                   Filter:
Ç                      Ord codes. E.g. "i||i" -> [105, 124, 124, 105]
3%                    Mod 3.          ->        [0, 1, 1, 0]
·                   Double.         ->        [0, 2, 2, 0]
Ì                  Add 2.          ->        [2, 4, 4, 2]
O                 Sum the prefix. ->        12
@}               Does it exceed
the second input? -> 50 >= 12 -> 1

θ              The last item of the filtered prefixes: "i||iii|"
D             Duplicate.
¹Ê           Is it not equal to the first inupt?     "i||iii|" != "i||iii|" -> 0
s          Swap the other copy up.                 "i||iii|"
{         Sort.                                   "iiii|||"
γ        Group by consecutive equal items.       ["iiii","|||"]
€g      Map: length.                            [3, 4]
‚     Pair.                                   [0, [3, 4]]

• Nice approach. Some things to golf: the leading S can be removed; the Os‹ can be O›; and the Dg¹g‹sJθ can be θD¹Ês: try it online - 20 bytes. – Kevin Cruijssen Jul 6 at 7:48
• I think you have an off by one error (or need to use >= in place of >) - e.g. this should return [0, [1, 1]]. Also is it acceptable to return [[],[]] when we can't cut the first tree, or [[0],[x]] when we make it through the first x trees which happen to be of the same type? – Jonathan Allan Jul 6 at 17:08

# JavaScript (Node.js), 52 bytes

Takes input as (b)(n), where b is a Buffer (using the characters described in the challenge) and n is the durability of the axe.

Returns a Boolean value and 2 integers as [ broken, [ small, big ]].

b=>n=>[b.some(c=>(n-=6&c+1)<0||!++a[c%3],a=[0,0]),a]


Try it online!

### How?

Given an ASCII code c, we use 6 & (c + 1) to get the number of swings needed to chop the tree, and c % 3 to get an index into the tree-counting array a[] (0 for small, 1 for big).

 char. | c = ASCII code | 6 & (c + 1) | c % 3
-------+----------------+-------------+-------
'i'  |       105      |      2      |   0
'|'  |       124      |      4      |   1


# R, 63 bytes

using characters exactly as described in challenge (or only 54 bytes using 0,1 to represent small & big trees, and outputting 0,1 to represent FALSE/TRUE axe breaking).

function(a,t)list(sum(c<-2+2*(t<"i"))>a,table(t[cumsum(c)<=a]))


Try it online!

# J, 3734 33 bytes

(](-:;+/@#:@])(>:2*+/\)#])' i'i.]


Try it online!

-1 byte thanks to Bubbler

Converts small to 1, big to 2. Now create a filter by doubling and scan summing, and apply filter to find entries less than or equal to the left input. Take just those entries, convert to binary, and sum to get the <num big>, <num small> part of the answer. Check if the filtered list equals the unfiltered list to get the "chops down all trees?" part of the answer.

• You can omit the last char | in ' i|'i.]. – Bubbler Jul 6 at 6:43

# Python 2, 103 $$\\cdots\$$ 82 80 bytes

Saved 4 6 9 11 bytes thanks to ovs!!!

f=lambda s,n:n<sum(6&ord(t)%6for t in s)and f('<'+s[:-1],n)or map(s.count,"<i|")


Try it online!

Inputs a string of trees $$\s\$$ (as is and |s) and an axe durability $$\n\$$.
Outputs a list of [axe broken, small trees, large trees] where axe broken is truthy if Tom's axe broke (or falsy otherwise) followed by the number of trees cut down.

How

If $$\c\$$ is either i, | or < then: $$\text{6&ord(c)%6} = \left\{ \begin{array}{ll} 2 \text{ if c is 'i'}\\ 4 \text{ if c is '|'}\\ 0 \text{ if c is '<'} \end{array} \right.$$

this is summed for all the trees in $$\s\$$ to calculate its needed durability. If it's too much for Tom's axe then we repeatedly try again without the last tree and set Tom's axe as broken by inserting a < into $$\s\$$, making that count truthy. When Tom's axe us strong enough we return what happened to his axe along with the number of each tree still in $$\s\$$.

• (h,[*map(s.count,"i|")]) for -4. – ovs Jul 6 at 19:39
• @ovs Nice one - thanks! :-) – Noodle9 Jul 6 at 20:14
• If you modify the output format slightly, it is 85 bytes – ovs Jul 6 at 20:45
• @ove Nice two - thanks again! :D – Noodle9 Jul 6 at 20:53
• A last one: if you output a truthy/falsy value instead of 1/0, 82 bytes (or 80 bytes in Python 2) are possible. – ovs Jul 6 at 21:13

# Keg, 32 bytes

0:&®s?⑷¦i2⑹|\|4©s⑨®s±™⑸¿⅀0=⑻©s(.


Try it online!

Takes input as trees, durability and outputs big, small and whether or not the axe breaks.

Somehow, Keg beat pyth.

# Jelly, 14 bytes

I'm assuming, for now, that the "boolean" part of the output may be given as a Truthy/Falsey value.

Og©2ḤÄ’<a®‘ċⱮ3


A dyadic Link accepting the trees (a list of characters) on the left and the axe durability (an integer) on the right which yields a list of three integers, [is_broken, small_trees, big_trees] (Note that non-zero integers are Truthy in Jelly while 0 is Falsey).

Try it online!

### How?

Og©2ḤÄ’<a®‘ċⱮ3 - Link: list of characters, T; integer, D   e.g. "|i|iii"; 14
O              - Ordinals (T)                                   [124,105,124,105,105,105]
©            - copy this to the register and yield it:
g 2           -   greatest common divisor with two             [2,1,2,1,1,1]
Ḥ          - double                                         [4,2,4,2,2,2]
Ä         - cumulative sums                                [4,6,10,12,14,16]
’        - decrement                                      [3,5,9,11,13,15]
<       - less than (D)?                                 [1,1,1,1,1,0]
a      - logical AND with:
®     -   recall the value from the register           [2,1,2,1,1,0]
‘    - increment                                      [3,2,3,2,2,1]
Ɱ3 - map across 3 with: (i.e. for right in [1,2,3])
ċ   -   count occurrences                            [1,3,2]


# Python 3.8, 109 bytes

f=lambda l,n,a=0,b=0:f(l[1:],m,a+1-j,b+j)if l and(m:=n-((j:='i|'.index(l[0]))+1)*2)>=0 else[l!=''and m<0,a,b]


Try it online!

• @Alexley I have a found a 107 byte solution by placing f= in the header.Try it online! – math Jul 11 at 12:39
• @Tanmay thanks for the sugession, but the function is recursive, so f is a part of the code. Alternatively, why don't we move all the function into the header instead?) $0$ bytes. – Alexey Burdin Jul 11 at 15:04

# Retina 0.8.2, 55 bytes

\d+
$* (11)+1?(?<-1>(i)|(?<-1>(\|)))*($)?.*
$#4$#3 $#2  Try it online! Takes input as [durability][trees] without a separator and outputs [complete] [big] [small]. Explanation: \d+$*


Convert the durability to unary.

(11)+1?


Capture half the durability as $#1. (?<-1>(i)|(?<-1>(\|)))*  Count the trees as they are matched, and decrement the remaining durability appropriately depending on the size of tree. ($)?.*


Determine whether the all of the trees were chopped down.

$#4$#3 \$#2


Output the desired results.