15
\$\begingroup\$

The Challenge

Given an input string (or array) consisting of < and >, output a sequence (array or string) of integers such that:

  • the operators are all correct when applied in order between consecutive numbers in the output
  • all integers are positive (1 or greater)
  • the sum of the integers is as small as is mathematically possible

Inputs can vary to match "greater than" and "less than" in your chosen language.

As an alternative output, just specify the sum of the numbers in the output. State which version you're solving in your Answer title.

Usual exclusions and rules apply, smallest bytes wins.

You can assume that the input string will never lead to an integer overflow in your language, if that helps.

Examples

  • > gives 2 1 which sums to 3
  • >>> gives 4 3 2 1 which sums to 10
  • >< gives 2 1 2 which sums to 5
  • gives 1 which sums to 1
  • >>>>>>>>> gives 10 9 8 7 6 5 4 3 2 1 which sums to 55
  • >><<>><>>> gives 3 2 1 2 3 2 1 4 3 2 1 which sums to 24
  • ><>><>><> gives 2 1 3 2 1 3 2 1 2 1 which sums to 18
  • <<<<> gives 1 2 3 4 5 1 which sums to 16
  • <<<<><<> gives 1 2 3 4 5 1 2 3 1 which sums to 22
  • >><< gives 3 2 1 2 3 which sums to 11
\$\endgroup\$
  • \$\begingroup\$ Can we use symbols other than > and <? \$\endgroup\$ – Erik the Outgolfer Mar 29 '18 at 17:11
  • \$\begingroup\$ @JonathanAllan I think it's the examples that are wrong, and you should assume that when answering, not that the spec is wrong. EDIT: Well, then I'm afraid they're invalid, since it's the spec that defines a challenge, not the test cases. \$\endgroup\$ – Erik the Outgolfer Mar 29 '18 at 17:50
  • 4
    \$\begingroup\$ Just waitin' for an answer in <><. \$\endgroup\$ – Khuldraeseth na'Barya Mar 29 '18 at 21:24
  • 1
    \$\begingroup\$ Massive apologies to everyone for messing up the examples! As for other characters, yes provided they have the same meaning in your language \$\endgroup\$ – simonalexander2005 Mar 29 '18 at 21:55
  • 3
    \$\begingroup\$ @Scrooble You spelled it wrong. It's ><> \$\endgroup\$ – Jo King Mar 30 '18 at 1:09

10 Answers 10

3
\$\begingroup\$

Jelly, 19 bytes

0;+×¥@\
=”<µCṚÇṚ»Ç‘

Try it online!

The value of each number is max( number of > immediately to the right of it , number of < immediately to the left of it ) + 1 .


Alternatively...

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I don't like languages requiring a program to transpile like Stax... well, Jelly is borderline. (require a program to compress strings) At least, Jelly still wins. \$\endgroup\$ – user202729 Mar 30 '18 at 10:22
  • \$\begingroup\$ except Dennis, who compresses strings by hand. \$\endgroup\$ – user202729 Mar 30 '18 at 10:45
  • \$\begingroup\$ Aesthetically, I don't really like it either. But the thing I like most of all in a golfing language is whatever allows its programs to be smallest. I still have a few ideas for stax about this one... \$\endgroup\$ – recursive Mar 30 '18 at 21:54
8
\$\begingroup\$

><>, 40 38 bytes

1v!rnr~<oa
?\i:0(?^3%\+$
{/?:-{:}-1/1:

Try it online!

An appropriate language. For reference ><> itself yields 2,1,2,1.

How it Works:

1v   Initialise the stack as 1 and enter loop
 \i:0(?^  If we're out of input, go to the first line
        3%\ Otherwise mod the input by 3, yielding 0 for < and 2 for >
        -1/Subtract 1 to get -1 and 1 respectively
    -{:}   Copy the previous number and subtract the above from it

 /?:    If the number is not 0, repeat the loop

?\        \+$  Otherwise:
                Increment each number until we reach the original 0
{/        /1:   And enter the first loop again

      ~<    When we're out of input, pop the extra -1 from EOF
   rnr      Output the first number
1v!         Push a 1 
        oa  Print a newline and repeat, popping the extra 1 each time
\$\endgroup\$
  • \$\begingroup\$ +1 for stating what value the language itself holds. :) (And because it's just a good answer as well, otherwise I wouldn't have +1-ed it.) \$\endgroup\$ – Kevin Cruijssen Mar 30 '18 at 7:27
5
\$\begingroup\$

Python 3, 93 bytes

k=0
for r in input().split('<'):p=len(r);print(max(k,p)+1,*range(p,0,-1),end=' ');k=1+(p<1)*k

Try it online!

Unscrambled:

# offset, will be explained later
k = 0 
for run in input().split('<'):
    # p = length of sequence of '>'s, which will produce p+1 decreasing integers
    p = len(run)
    # will print:
    # p+1 p p-1 ... 1    or    k+1 p p-1 ... 1
    print(max(k, p) + 1, *range(p, 0, -1), end=' ')
    # offset of the next sequence: (i.e. -1 + the minimal value of the first integer)
    k = 1 + (k if p > 0 else 0)
\$\endgroup\$
  • 1
    \$\begingroup\$ This is my first golf! \$\endgroup\$ – Fons Mar 30 '18 at 13:17
5
\$\begingroup\$

Haskell, 119 bytes

n%">"=r[1..n]
n%"<"=[1..n]
n%(c:b)|c==b!!0=(n+1)%b|a:s<-2%b,e:z<-r$n%[c]=r z++last(max:[min|c>'<'])a e:s
r=reverse
(2%)

Try it online!

Explanation

The idea here is that we have runs of either >s or <s, which each map to ascending and descending ranges. So we use group to split the string into groups of consecutive characters. Our job is to then stitch these together in the proper fashion.

When we have <> we want to stitch the two lists together taking the larger end value for example

<<<<<<>>

is split

<<<<<<  >>

mapped to ranges

[1,2,3,4,5,6,7] [3,2,1]

Then when we stitch we drop 3 because it is smaller (3 isn't larger than 7).

 [1,2,3,4,5,6,7,2,1]

When we have >< we do the opposite, we drop the larger value.

The actual code attains this by making an operator %. The definition of % is quite complex, but basically it reads from left to right keeping track of how many consecutive characters are the same. It does this in the left had value of the operator. When we reach a place where the characters change we perform the stitching as I described.

\$\endgroup\$
  • \$\begingroup\$ What's the purpose of the last line (2%)? \$\endgroup\$ – siracusa Mar 29 '18 at 22:36
  • \$\begingroup\$ @siracusa That is the function itself. It is a pointfree function, so it basically says call % with 2 as the first argument. \$\endgroup\$ – Sriotchilism O'Zaic Mar 29 '18 at 23:05
  • \$\begingroup\$ Is that a common practice here to just put the final function call on the last line instead of adding a full main implementation? \$\endgroup\$ – siracusa Mar 29 '18 at 23:30
  • 1
    \$\begingroup\$ @siracusa Yes. Submissions are allowed as named functions, anonymous functions or as complete programs. This is an anonymous function. I choose anonymous simply because it is the shortest. \$\endgroup\$ – Sriotchilism O'Zaic Mar 29 '18 at 23:37
  • \$\begingroup\$ @siracusa See our Guide to Golfing Rules in Haskell. \$\endgroup\$ – Laikoni Mar 30 '18 at 10:24
4
\$\begingroup\$

Retina 0.8.2, 36 bytes


1
{`\b(1+)>\1
1$&
}`(1+)<\1\b
$&1
1

Try it online! Link includes test cases. Explanation:


1

Insert 1s before, between and after the <s and >s.

{`\b(1+)>\1
1$&
}`(1+)<\1\b
$&1

Repeatedly increment integers until all the comparisons are satisfied.

1

Sum the integers and convert to decimal.

\$\endgroup\$
3
\$\begingroup\$

Java 10, 198 181 bytes

s->{var p=s.split("(?<=(.))(?!\\1)");int l=p.length,L[]=new int[l],i=l,r=0,a,b;for(;i-->0;r+=a*-~a/2-(i<l-1?p[i].charAt(0)<61?a<(b=L[i+1])?a:b:1:0))a=L[i]=p[i].length()+1;return r;}

Try it online.

Explanation:

s->{                      // Method with String parameter and integer return-type
  var p=s.split("(?<=(.))(?!\\1)");
                          //  Split the String into parts
                          //  (i.e. ">><<>><>>>" becomes [>>, <<, >>, <, >>>])
  int l=p.length,         //  Get the amount of parts
      L[]=new int[l],     //  Create an integer-array of the same size
      i=l,                //  Index-integer, starting at this size
      r=0,                //  Result-integer, starting at 0
      a,b;                //  Two temp integers to reduce the byte-count
  for(;i-->0;             //  Loop downwards over the array; range: (`l`,0]
      ;r+=                //    After every iteration: increase the result with:
          a*-~a/2         //     The triangle number of the current item
        -(i<l-1?          //     If it's not the last item:
           p[i].charAt(0)<61?
                          //      And the order of the current and previous is "<>":
            a<(b=L[i+1])? //       If the current item in `L` is smaller than the previous:
             a            //        Subtract the current item
            :             //       Else (the current is equal or larger than the previous):
             b            //        Subtract the previous item
           :              //      Else (the order of the two parts is "><" instead):
            1             //       Subtract 1
          :               //     Else (it's the last item in `L`):
           0))            //      Leave the result `r` unchanged
    a=L[i]=               //   Set both `a` and the current item in `L` to:
     p[i].length()+1;     //    The length of the part + 1
  return r;}              //  Return the result
\$\endgroup\$
3
\$\begingroup\$

Haskell, 87 bytes

r=reverse
s#c=(+1).length.takeWhile(==c)<$>scanr(:)[]s
f s=zipWith max(s#'>')$r$r s#'<'

Try it online!

A port of my Jelly answer.

\$\endgroup\$
2
\$\begingroup\$

Stax, 21 bytes

éda╓~/└↨☺∟╒←║ç Γφ5←9h

Run and debug it

It works by run-length encoding the input, and then concatenating generated ranges together. Unpacked, ungolfed, and commented, it looks like this.

|R      run-length encode
{       begin block
  H^R   range from [1 .. run length]
  _hh|1 -1 ** (character code / 2)
  *     multiply run; this will reverse it iff character is '>'
m       map runs using preceding block
O       push a 1 under the top of stack
{       begin block
  h|M   get the start of the generated range, and take max of it and top of stack
  _DE   push the rest (tail) of the generated range to the stack
F       foreach generated range
L|+     sum of all values on the stack

Run this one

\$\endgroup\$
2
\$\begingroup\$

Perl 5 -p, 53 bytes

#!/usr/bin/perl -p
s//1/g;1while s/(?=\b(1+)>\1)|(1+)<\2\b\K/1/;$_=y/1//

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ This answer seems to have been implemented based off of the test cases instead of the challenge specification. Unfortunately, they have been identified as wrong. \$\endgroup\$ – Erik the Outgolfer Mar 29 '18 at 17:58
  • 1
    \$\begingroup\$ @EriktheOutgolfer Fixed \$\endgroup\$ – Ton Hospel Mar 30 '18 at 10:08
1
\$\begingroup\$

Red, 185 bytes

func[s][repeat n 1 + length? s[l: 0 i: n - 1 while[i > 0 and(s/(i) = #"<")][i:  i - 1 l: l + 1]r: 0 i: n while[(i <= length? s)and(s/(i) = #">")][i: i + 1 r:
r + 1]prin[1 + max l r""]]]

After user202729's explanation...

Try it online!

f: func[s][
   repeat n 1 + length? s[
       l: 0
       i: n - 1
       while [i > 0 and (s/(i) = #"<")][ 
           i: i - 1
           l: l + 1
        ]
        r: 0
        i: n
        while [(i <= length? s) and (s/(i) = #">")][
            i: i + 1
            r: r + 1
        ]
        prin[1 + max l r ""]
    ]
]
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.