title: s-n-a-k-e-a-r-o-u-n-d--->

text:
# Question
Title: s-n-a-k-e-a-r-o-u-n-d--->
This challenge is about walking around a string like a snake.

```
s-n-a-k
.---. e
d <-' a
n-u-o-r

```

You will be given a string \\$ S \\$ of length \\$ l \\$ and a positive integer \\$ n \\$ where \\$ n ^ 2 \ge l + 1 \\$.

The string rotates 90° after writing \\$ n \\$ characters of \\$ S \\$, or when it hits itself. When \\$ S \\$ is being written horizontally, characters are delimited by hyphens `-`. When it is being written vertically, there is no delimiter.

Once all characters of \\$ S \\$ have been exhausted, continue to fill the snake with hyphens and pipes `|`, with periods `.` at corners at the top of the spiral and single-quotes `'` at corners by the bottom of the spiral.

The final character of the spiral will be either `<` or `>`, depending on the direction the spiral is facing when it finishes.

When the snake has been constructed, output it in any reasonable way. The output may contain any whitespace that does not affect the snake's appearance, e.g. a fixed amount of leading whitespace on each line.

You can assume \\$ S \\$ will only contain mixed-case letters of the English alphabet. It will never be an empty string, but always have at least 1 character.

Here are some examples to test your program against:

```
S = snakearound

n = 4:

s-n-a-k
.---. e
d <-' a
n-u-o-r

n = 5:

s-n-a-k-e
.-----. a
| .-> | r
| '---' o
'---d-n-u

n = 6:

s-n-a-k-e-a
.-------. r
| .---. | o
| | <-' | u
| '-----' n
'---------d

n = 7:

s-n-a-k-e-a-r
.---------. o
| .-----. | u
| | .-> | | n
| | '---' | d
| '-------' |
'-----------'

==============

S = noodleman

n = 4:

n-o-o-d
.---. l
| <-' e
'-n-a-m

n = 6:

n-o-o-d-l-e
.-------. m
| .---. | a
| | <-' | n
| '-----' |
'---------'

==============

S = TheQuickBrownFoxJumps

n = 5:

T-h-e-Q-u
x-J-u-m i
o .-> p c
F '---s k
n-w-o-r-B

=============

S = pleaseno

N = 3:

p-l-e
o—> a
n-e-s

```

This is , so the shortest code per language, measured in bytes, wins.

# Answer
> 9 votes
# K (ngn/k), ~~337~~ ~~331~~ ~~315~~ ~~290~~ ~~279~~ ~~231~~ ~~224~~ ~~211~~ 213 bytes

```
{(x,w)#@[(x*w)#" ";i,*|i;:;@["|-"{1|1=x|-x}@-':i:0,+\(,/-:\1,w:-1+2*x)4!2_&s;(-2_-2+\s;!#y);:;(".''."4!!-2+#s:,/+|1(2*1+)\|!x; y:,/((#l)#("-";"")){x/y}',''l:(0,((#y)>)#+\(0,(-1+#l)#-1 1)+l:1_|1+&x#2)_y)],"<>"2!x]}

```

Try it online!

-6 : Save a few bytes with shorter names.
-16 : Tidying up
-25 : Cruft
-46 : Golfing gets me back under limits
-7 : Cleaner
-13 : A single statement!
+2 : handle empty string

# Answer
> 6 votes
# Pyth, 78 bytes

```
ju&K>*hhHH+z>s.i_Psm*Rd"-|"Qs@L_B".'"tQlz.e++b?%klGd\-@K+Hk+j\-<KH__MGStQ]@"<>

```

Try it online!

# Answer
> 5 votes
# Python 3, ~~371~~ ~~274~~ 255 and 253 bytes

```
def f(s,n):
 for y in(a:=range(n)):
  for x in a:r=min(x,y,n+~x,n+~y);i=4*r*(n-r)-2*r+x+y+2*(2*(n+~r)-x-y)*(y>x);H=max(n+~y,y)>x>min(y-2,n-y-2);b=x+1>n/2;print(s[i:]and s[i]or"|-..''><"[H+2*((n+2*~x)*b-~x==y)+4*((n+~x-x)*b+x==n+~y)],end=" -"[H])
  print()

```

Try it online!

Minus 64 bytes thanks to @noodleman and another 11 bytes thanks to @Kevin Cruijssen! I then saved another 22 bytes. Most recent improvement of 6 bytes by @xnor and 13 bytes by me.

Instead of most other solutions (as far as I can tell), I tried calculating the index into the string. I dug up a post on StackOverflow that helped with this, though a lot was just throwing random equations and seeing what they do. Maybe the indexing equation can be simplified with a bit more thought, but it's surprisingly short already.

There are lots of places where `-x-1` is replaced with `+~x` (or variants). Booleans are heavily used for indexing and cancelling parts of equations with multiplication.

Ungolfed:

```
def function(string: str, number: int):
  for y in range(number):
    for x in range(number):
      rounds = min(x, y, number - x - 1, number - y - 1)
        # total increments after `rounds` revolutions and fix for overcounting
      index = 4 * rounds * (number - rounds) - 2 * rounds
      index += x + y  # east + south increment
      index += 2 * (2 * (number - rounds - 1) - x - y) * (y > x)  # west + north

      # See below for explanation
      is_horizontal = max(number - y - 1, y) > x > min(y - 2, number - y - 2)
      is_right = x + 1 > number / 2
      # Both inlined
      is_up_corner = x + 1 + is_right * (number - 2 * (x + 1)) == y
      is_down_corner = x + is_right * (number - 1 - 2 * x) == number - y - 1

      # is_middle = x + 1 - number % 2 == y == number // 2
      # is_middle = is_up_corner and is_down_corner
      # is_down = y > number / 2
      # is_left_corner = y + is_down * (number - 2 * y) == x + 1
      # is_right_corner = y + is_down * (number - 1 - 2 * y) != number - x - 1

      print(
        # string[index] if index < len(string) else
        string[index:] and string[index] or \
        # See below for explanation
        "|-..''><"[is_horizontal + 2 * is_up_corner + 4 * is_down_corner],
        end=" -"[is_horizontal]
      )
    print()

```

Explanation of `is_horizontal` boolean: There are effectively four quadrants in which we need to determine whether the coordinate is a horizontal part in the snake, we can do this for the upper right corner with `number - y - 1 > x`. On its own this is not enough, because the lower part of the snake is now messed up. Taking `y > x` works for the lower right quadrant, but messes up the snake above. Combining these two equations into `max(number - y - 1, y) > x` leaves only the left part of the snake to fix. Creating conditions for the other corners you can combine `x > min(y - 2, number - y - 2)` into one large expression.

```
------------.                 ------------.                 ------------.
.---------. |                 .---------. |                 .---------. |
--.-----. | |                 --.-----. | |                 | .-----. | |
----.-> | | |     becomes     ----.-> | | |     becomes     | | .-> | | |
----' | ' | |                 ----'---' | |                 | | '---' | |
--' | | | ' |                 --'-------' |                 | '-------' |
' | | | | | '                 '-----------'                 '-----------'

```

Explanation of special character indexing into `|-..''><`: There are six special characters that we need to index into, which can be separated into three categories: Straight, corner and tail. By virtue of the equations, we can determine we need a tail if something is both an up- and down-corner. Obviously, if it is not a corner or tail, it should be a straight piece. Using the equation `is_up_corner + 2 * is_down_corner` we can differentiate the four cases straight, up-corner, down-corner, and tail. To select the correct straight and tail pieces we still need a more granular distinction. Using `is_horizontal` obviously works for straight pieces and additionally it works for the tail, because the left-pointing arrow has an appendage whereas the right-pointing does not. This can be combined with the previous equation by doubling the corners.

## 253 bytes solution

This solution outputs not a string, but a nested array/matrix of characters. This might be allowed according to the meta post: Strings and arrays of characters are interchangeable.

It's effectively the same as the above, but also returns instead of prints. It unfortunately requires `*''.join()` in the inner loop, because you cannot populate an array with two items per iteration. (And by doubling the iterations I only managed to golf to 255.)

```
lambda s,n:[[*''.join((r:=min(x,y,n+~x,n+~y),i:=4*r*(n-r)-2*r+x+y+2*(2*(n+~r)-x-y)*(y>x),H:=max(n+~y,y)>x>min(y-2,n-y-2),b:=x+1>n/2,s[i:]and s[i]or"|-..''><"[H+2*((n+2*~x)*b-~x==y)+4*((n+~x-x)*b+x==n+~y)])[4]+" -"[H]for x in range(n))]for y in range(n)]

```

Try it online!

# Answer
> 5 votes
# Python 3.8, ~~254~~ 247 bytes

```
lambda n,s:(r:=range,G:=["<>"[n%2]],[(K:=(s+''.join((2*[(n+~h//4)*"-",(n-2-h//4)*"|"],".''.")[h%2][h//2%4]for h in r(4*n))[len(s):])[~(f+1)**2:],G:=['-'.join(K[:f+1])]+[G[~g][::-1]+"- "[f-g>1]+K[f-~g]for g in r(f)])for f in r(1,n)])and'\n'.join(G)

```

Try it online!

Essentially a port of my Pyth answer.

I'll hand wave a bit of an explanation. We start by assigning `G` to the center of the spiral, `n` being even or odd determines if the arrow points left or right. Next we construct the string for the spiral as if `s` was an empty string, then replace the beginning of that string with `s`. We then build the rest of the square, each iteration we flip `G` 180 degrees and add to the top and the right side. After `n-1` iterations of this, we return `G` joined on newlines.

# Answer
> 5 votes
# Python 3.8 (pre-release), ~~239~~ ~~209~~ ~~205~~ ~~204~~ ~~199~~ ~~197~~ 196 bytes

```
def f(s,n):
 i=n%-2;g="--.\n<-'>"[i:7-i]
 while(i:=i+2)<n:m="--"*i;g=m+f"--.\n.-%s |\n'{m}-'"%g.replace("\n"," |\n| ")
 z=d=0;*a,=g
 for c in s:d+=a[z]in".'";a[z]=c;z+=2*(1,n,-1,-n)[d%4]
 return a

```

Try it online!

I was able to simplify again by a significant amount. Now the output is a simple array of characters (this is better than before).

The recursive function `g` makes an empty snake, function `f` fills in the given string `s`.

* minus 30 bytes by simplification of function `g`
* minus 4 bytes by inlining the function `g` (now non-recursive)
* minus 1 byte thanks to c--
* minus another 5 bytes thanks to c-- !
* minus 2 bytes by using f-string and formatting
* minus 1 byte thanks to c--

## Here are my older versions:

### Python 3.8 (pre-release), ~~271~~ ~~269~~ ~~257~~ 254 bytes

This new version (built from the 275 bytes solution) stretches the output rules to the maximum, or even beyond? The output array contains iterables as elements, either strings or arrays of strings. By `"".join(e)` we always get a string out of element `e`.

* Minus 2 bytes, thanks to an idea of noodle man!
* Minus 12 bytes by myself, using new algorithm for spiral
* Minus 3 bytes by myself - small improvement

```
g=lambda n:[(m:="-"*(2*n-3))+"-."]+[".|- "[i>0::2]+g(n-2)[i]+" |"for i in range(n-2)]+[f"'{m}'"]if n>2else["--.",">","<-'"][n<2::2]
def f(s,n):
 z=d=0;a=g(n)
 for c in s:l=list(a[z//n]);d+=l[z%n*2]in".'";l[z%n*2]=c;a[z//n]=l;z+=(1,n,-1,-n)[d%4]
 return a

```

Try it online!

### Python 3.8 (pre-release), ~~361~~ ... 275 bytes

* Minus 18 bytes, thanks to noodle man!
* Minus 18 bytes additionally by myself
* Minus 9 bytes by myself
* Minus 9 bytes by myself
* Minus 11 bytes by myself
* Minus 20 bytes by returning a 2 dimensional array, thanks to noodle man!
* Minus 1 byte by myself

```
g=lambda n:[(m:="-"*(2*n-3))+"-."]+[".|- "[i>0::2]+g(n-2)[i]+" |"for i in range(n-2)]+[f"'{m}'"]if n>2else["--.",">","<-'"][n<2::2]
def f(s,n):
 x,y,k,a=0,0,7,[list(s)for s in g(n)]
 for c in s:k=(7-5*(k>6),-5*(k>1),k)[".'".find(a[y][x])];a[y][x]=c;x+=k//3;y+=k%3-1
 return a

```

Try it online!

Recursive, but not shortest, unfortunately.

Function `g` makes an empty snake, function `f` fills in the string.

# Answer
> 5 votes
# BASH , ~~580 349 308 303 291 286 283 277 275 272~~ 271 bytes

Found this very entertaining, thanks! First variant was 580 bytes, then 349, ..., now 271:

```
s=$1 n=$2 N=$[n+n-1];f(){ b=$1;for((j=1;j<n;j++));{((c<N))&&T+=%s;[[ $4 ]]&&h=$4 S[i+$2/2]=-;t=${s:c:1} S[i]=${t:-$b} b=$3;$[i+=$2,c++];S[i-($2/N)]=\ ;};};while((n>0));do f . 2 - \>;$[n-=a];f . $N \|;f \' -2 - \<;$[n--];f \' -$N \|;a=1;done;S[i]=$h;printf $T\\n "${S[@]}"

```

Try it online!

Squeezed to 271(with `2>/dev/null`):

```
#!/bin/bash
s=$1 n=$2 N=$[n+n-1]
f(){
    b=$1
    for((j=1;j<n;j++)); {
        ((c<N))&&T+=%s
        [[ $4 ]]&&h=$4 S[i+$2/2]=-
        t=${s:c:1} S[i]=${t:-$b} b=$3
        $[i+=$2,c++]
        S[i-($2/N)]=\
    }
}
while((n>0));do
    f .  2    - \>; $[n-=a]
    f .  $N  \|
    f \' -2   - \<; $[n--]
    f \' -$N \|   ;   a=1
done;S[i]=$h;printf $T\\n "${S[@]}"

```

First variant was:

```
#!/bin/bash

s=$1
n=$2
l=${#s}
N=$((n+n-1)) # items per row

# Check if n is in range
(( (n*n)>=(l+1) )) || { echo "n must be 'n^2≥l+1'"; exit 1; }

# Fill the 'area' with spaces
for ((i=0; i<n*N; i++)); { snake[$i]=" "; }

# Create printing template
printf -v row "%${N}s"
row=${row// /%s}

# Setcounters
i=0
c=0
a=0

forward(){
    b='.'
    for ((j=1; j<n; j++)); do
        cut=${s:c:1}
        snake[$i]=${cut:-$b}
        snake[$((i+1))]="-"
        b='-'
        h='>'
        ((i+=2))
        ((c++))
    done
    ((n-=a))
}

down(){
    b='.'
    for ((j=1; j<n; j++)); do
        cut=${s:c:1}
        snake[$i]=${cut:-$b}
        b='|'
        ((i+=N))
        ((c++))
    done
}

back(){
    b="'"
    for ((j=1; j<n; j++)); do
        cut=${s:c:1}
        snake[$i]=${cut:-$b}
        snake[$((i-1))]="-"
        h='<'
        b='-'
        ((i-=2))
        ((c++))
    done
    ((n--))
}

up(){
    b="'"
    for ((j=1; j<n; j++)); do
        cut=${s:c:1}
        snake[$i]=${cut:-$b}
        b='|'
        ((i-=N))
        ((c++))
    done
    a=1
}

print(){
    printf "$row\n" "${snake[@]}"
#    echo $i,$c,$n
}

# Create snake
while ((n>0)); do
    forward
    down
    back
    up
done
snake[$i]=$h; printf "$row\n" "${snake[@]}"

```

Try it online!

# Answer
> 4 votes
# JavaScript (ES12), 188 bytes

Expects `(string)(n)`. Returns a matrix of characters.

```
s=>n=>eval(`for(m=[k=x=y=0];~n;)for(d=-2;i=~n&&d++<2;n-=!n|d&!!y)for(;i++<(d&1?w=n*2-1:n||2);x-=d%2,y-=~-d%2)(m[y]||=[..."".padEnd(w)])[x]=d*x+1&1&&s[k++]||"|-..''< >"[i>2?d&1:d-3*~!n];m`)

```

Attempt This Online!

### Alternate formula

I've found the following alternate formula for special characters where each entry appears only once in the lookup string. But in the end, it's just as long as the simpler one.

```
".<'>|-"[i > 2 ? d & 1 | 4 : !n ^ d * 3 & 2]

```

### Commented

This is a version without `eval()` for readability.

```
// s = input string, n = size parameter
s => n => {
  for(
    // m[] is the output matrix
    // k is a pointer into s
    // (x, y) is the current position in the matrix
    m = [k = x = y = 0];
    // stop when n = -1
    ~n;
  )
    for(
      // d is the direction
      d = -2;
      // stop when n = -1 or d = 2
      // i is the counter for the next loop
      i = ~n && d++ < 2;
      // decrement n if n = 0, or d is odd and y != 0
      n -= !n | d & !!y
    )
      for(
        ;
        // the width is 2n-1 if d is odd, or n if d is even
        // there's a special case for the last iteration
        i++ < (d & 1 ? w = n * 2 - 1 : n || 2);
        // (x, y) <- (x + dx, y + dy)
        x -= d % 2,
        y -= ~-d % 2
      )
        // if m[y] is undefined, initialize it to w spaces
        (m[y] ||= [..."".padEnd(w)])[x] =
          // if either d or x is even, attempt to get the next
          // character from s
          d * x + 1 & 1 && s[k++]
          // if falsy or undefined, use a special character:
          // - "|" or "-" for segments (i > 2)
          // - "." or "'" for corners (i = 2, n ≠ 0)
          // - "<" or ">" for the final character (i = 2, n = 0)
          || "|-..''< >"[i > 2 ? d & 1 : d - 3 * ~!n];
  return m
}

```

# Answer
> 3 votes
# Charcoal, 61 bytes

```
Ｆ⮌Ｓ⊞υιＮηＦ⊖η«Ｆ⊖⁻ηι⎇υ⁺⊟υ-²↷²⎇υ⊟υ§.'ιＦ⁻⁻ηι²⎇υ⊟υ¹↷²⎇υ⊟υ§'.ι¹»§<>η

```

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

```
Ｆ⮌Ｓ⊞υι

```

Get the reverse of the input into a stack, so that characters can be processed by popping from it.

```
Ｎη

```

Input `n`.

```
Ｆ⊖η«

```

Repeat `n-1` times. The loop counter is taken as an ascending number for the purposes of calculating which corner character to print, but for the side lengths I show how the actual number of repetitions of the inner loops vary.

```
Ｆ⊖⁻ηι

```

Repeat from `n-1` down to once...

```
⎇υ⁺⊟υ-²

```

... output the next character followed by a `-`, or two `-`s if none.

```
↷²

```

Start moving vertically.

```
⎇υ⊟υ§.'ι

```

Output the next character or `.` or `'` appropriately if there are none left.

```
Ｆ⁻⁻ηι²

```

Repeat from `n-2` down to zero...

```
⎇υ⊟υ¹

```

... output the next character or `|` if there are none left.

```
↷²

```

Start moving horizontally, but in the other direction.

```
⎇υ⊟υ§'.ι¹

```

Output the next character or `'` or `.` appropriately if there are none left.

```
»§<>η

```

Output the head of the snake.

# Answer
> 3 votes
## Javascript, ~~384~~ ~~371~~ ~~304~~ ~~288~~ ~~263~~ 235 bytes

```
s=(S,n)=>(t=[...S],A=Array,a=A.from(A(n),r=>A(2*n).fill(e=' ')),x=y=0,p=(b,d,f)=>(a[y][x]=x&1&&t.shift()||b[d],f?.(d)),i=2*n-1,m=d=>(z=d&2,d&1?y+=1-z:x+=1-z,--i?p('-|-|',d,m):n<2?p('>><<',d):(i=d&1?2*--n:n-1,p("..''",++d%4,m))),m(0),a)

```

-13 bytes saved thanks to Samathingamajig
-67 bytes by folding functions `u()` and `d()` into `v(±1)` and `l()` and `r()` into `h(±1)`
-16 bytes with only one recursive function
-25 bytes because of this
-28 bytes with more golfing

### Try out

```
s=(S,n)=>(t=[...S],A=Array,a=A.from(A(n),r=>A(2*n).fill(e=' ')),x=y=0,p=(b,d,f)=>(a[y][x]=x&1&&t.shift()||b[d],f?.(d)),i=2*n-1,m=d=>(z=d&2,d&1?y+=1-z:x+=1-z,--i?p('-|-|',d,m):n<2?p('>><<',d):(i=d&1?2*--n:n-1,p("..''",++d%4,m))),m(0),a)

;[
  [ 'snake', 4 ],
  [ 'snakearound', 5 ],
  [ 'snakearoundandround', 6 ]
]
.forEach(([ S,n ]) => {
  console.log(s(S,n).map(r=>r.join('')).join('\n'))
})
```

## Ungolfed

```
s = (S,n) => {
  t = [...S];
  a = Array.from(Array(n), r => Array(2*n).fill(e=' '));
  x = y = 0;
  p = (b,d,f) => {            // set letter in all odd positions until
                              // exhausted, otherwise use snake
    a[y][x] = x&1 && t.shift() || b[d];
    f?.(d);                   // recurse unless end
  }
  i = 2*n-1;                  // counter for going in the same direction
  m = d => {
                              // the next position is set before p is called
    z = d&2;                  // forward or back?
    if (d&1) {                // vertical or horizontal?
      y+=1-z;
    } else {
      x+=1-z;
    }
    if (--i) {               // go on
      p('-|-|', d, m);
    } else if (n<2) {        // stop
      p('>><<', d);
    } else {                 // next direction
      i = d&1 ? 2*--n : n-1; // set going length, decrement n if horizontal
      p("..''", ++d%4, m);
    }
  }
  m(0);
  return a;
}

```

# Answer
> 2 votes
# Python3, 425 bytes

```
R=range
def f(n,s):
 r=[[' ']*2*n for x in R(n)];x=y=X=K=0;Y=C=1
 while 1:
  K+=1
  if s:r[x][y]=['-',s[0]][C%2or X!=0];s=s[C%2or X!=0:];C+=1
  else:r[x][y]='-|'[X!=0]
  if(y+Y==2*n-1or(0<=y+2*Y<2*n-1and' '!=r[x][y+2*Y])or Y<-y)and Y:
   if K==2:r[x][y]='<>'[Y>0];return r
   if r[x][y]in'-|':r[x][y]="'."[Y>0]
   X=Y;Y=0
  elif(x+X==n or' '!=r[x+X][y])and X:
   if r[x][y]in'-|':r[x][y]="'."[X<0]
   Y=-X;X=C=K=0
  x+=X;y+=Y

```

Try it online!

# Answer
> 2 votes
# Perl 5, ~~236~~ ~~224~~ ~~222~~ ~~214~~ 190 bytes

* minus 24 bytes, thanks to: good old time!

```
sub g{my$m="--"x($n=-2+pop);$m?"$m--.\n.-@{[g($n)=~s/\n/ |\n| /gr]} |\n'$m-'":$n?">":"--.\n<-'"}sub f{$a=g$p=pop;$z+=(1,$p,-1,-$p)[($#_+=(substr$a,2*$z,1,$_)=~/[.']/)%4]for$_[$z=0]=~/./g;$a}

```

Try it online!

I have derived this from my Python answer. Function `g` makes an empty snake, function `f` fills in the string.

Here is the same code with a little more spacing for better readability:

```
sub g{
  my$m="--"x($n=-2+pop);
  $m?"$m--.\n.-@{[ g($n)=~s/\n/ |\n| /gr ]} |\n'$m-'":$n?">":"--.\n<-'"
 }
sub f{
  $a=g$p=pop;
  $z+=(1,$p,-1,-$p)[($#_+=(substr$a,2*$z,1,$_)=~/[.']/)%4] for $_[$z=0]=~/./g;
  $a
}

```

# Answer
> 2 votes
# AWK, 332 321 317 281 273 257 bytes

```
func R(C){r=++c<A*A?length($1)<c?i<A?C:S%2?"'":".":substr($1,c,1):S%2?"<":">";g[x,y]=S%2?G r:r G}func f(){for(x=c=S=i=0;i<A=$2;R(B="-",G=++i<A?B:""))y=i;while(S++<=A){for(i=S;i++<A;R("|",G=i<A?" ":B))x+=t=S%2*2-1;for(i=S;i++<A;R(B,G=i<A?B:""))y-=t}return G}

```

Try it online!

* -11 bytes, replaced `condition ? var = val1 : var = val2` with `var = condition ? val1 : val2`
* -4 bytes, replaced `function` with `func`
* -36 bytes, thanks to @ceilingcat. Chained `=`, chained ternary operator and other optimization
* -8 bytes, thanks to @ceilingcat
* -16 bytes, thanks to @ceilingcat. Passed ternary operator as second arg for `func R(C)` and moved incrementation of `c` in same function to allow more efficient one-liner loop.

---

## Ungolfed

<pre><code>function result(string2)
{
    rep = string2
    if ( i == $2-1 ) step % 2 ? rep = "'" : rep = "."
    if ( length($1) > cpt ) rep = substr($1, cpt+1, 1)
    if ( cpt == ($2 * $2)-1 ) step % 2 ? rep = "<" : rep = ">"
    return rep
}

function snakearound()
{
    x = 0
    y = 0
    cpt = 0
    step = 0
    for(i = 0; i < $2; i++)
    {
        grid[x, y] = result("-")
        if (i+1 < $2) grid[x, y] = grid[x, y] "-"
        cpt++
        y++
    }
    y--
    while(step <= $2)
    {
        step++
        step % 2 ? tmp = 1 : tmp = -1
        for(i = step; i < $2; i++)
        {
            x += tmp
            grid[x, y] = result("|")
            i == $2-1 ? string = "-" : string = " "
            step % 2 ? grid[x, y] = string grid[x, y] : grid[x, y] = grid[x, y] string
            cpt++
        }
        for(i = step; i < $2; i++)
        {
            y -= tmp
            grid[x, y] = result("-")
            i == $2-1 ? string = "" : string = "-"
            step % 2 ? grid[x, y] = string grid[x, y] : grid[x, y] = grid[x, y] string
            cpt++
        }
    }

    for(i = 0; i < $2; i++){
        for(j = 0; j < $2; j++) printf("%s", grid[i, j])
        printf("\n")
    }
}
```
</code></pre>

# Answer
> 2 votes
# JavaScript (Node.js), ~~193~~ ~~192~~ ~~190~~ ~~188~~ ~~187~~ ~~182~~ 177 bytes

```
s=>n=>s.map(c=>a[d*=/[.']/.test(a[z-=d])?d*d<5?n:-1/n:1,z]=c,d=z=-2,a=[...g(n)])&&a
g=(n,m)=>--n?(m="--".repeat(--n))+`--.
${n?`.-${g(n).split`
`.join` |
| `} |
'`+m:"<"}-'`:">"

```

Try it online!

Now even shorter than Arnauld's excellent answer!

* Minus 5 bytes thanks to noodle man!
* Minus 5 bytes by clever improvement thanks to Arnauld!

This answer has been derived from my Python solution.

Function `g` makes an empty snake and function `f` updates it with the chars from string `s`. The function has to be called by `f(s,n)` and returns a plain array of single char strings.

# Answer
> 1 votes
# Perl 5, 255 244 bytes

```
sub r{$a='';$a.=$/while s/.$/$a.=$&;''/emg;$_=$a}sub f{($s=pop.'-'x--($n=2*pop)**2)=~s/.\K/-/g;$k=local$_=($"x$n.$/)x$n;r while s@ +$|>(  )+@$_=substr$s,0,-1+length$&,'';s/^-/$k&2?"'":'.'/e;$k++&1&&y/-/|/;"$_>"@me;$n&2&&y/>/</||r&r;s/.\K.//g;r}

```

Try it online!

Here's with newlines for better readability:

```
sub r{$a='';$a.=$/while s/.$/$a.=$&;''/emg;$_=$a}
sub f{
($s=pop.'-'x--($n=2*pop)**2)=~s/.\K/-/g;
$k=local$_=($"x$n.$/)x$n;
r while s@ +$|>(  )+@
$_=substr$s,0,-1+length$&,'';
s/^-/$k&2?"'":'.'/e;
$k++&1&&y/-/|/;
"$_>"
@me;
$n&2&&y/>/</||r&r;
s/.\K.//g;
r
}

```

I'm sure there are glaring opportunities to golf it further, but at least, for now, it's decently competitive with other answers, considering sigils. I was more interested to play with algorithm -- the square-ish string is actually rotated while being filled. Replace `r while...` with `print && r while...` to see intermediate steps.

P.S. It's funny to watch how snake's head moves and serves as anchor where to place the next fragment.

**Edit:** Just a little bit shorter. Rotation subroutine is also slightly less ugly and can now handle rectangular (not just square) shapes (but of course there ought to be Perl golfing pre-fab somewhere for the purpose, 20-odd years old, so I'm re-inventing the wheel), which fact was immediately used and lead to another couple bytes off.

In fact `local` can be ditched (-5) and TIO's footer written so that the `$_` doesn't hold read-only value while testing. And further couple bytes less if string is temporarily padded with arbitrarily large number of hyphens (`1E6`, say) instead of value computed from `n`. But I'm not that much desperate, yet :)

# Answer
> 1 votes
# 05AB1E, 86 bytes

```
LR·<€D¬šIõ¹·nи«'-ýŽ9¦S.Λ¶¡ιн»¶«„ -Â‚Dð¶:«D'-'|::2äε„|-Â‚D'|„.'Nè::¹N+ÉiNi'''<.;ë¨'>«]J

```

Inputs in the order \\$n,S\\$, where \\$S\\$ is a list of characters.
Outputs with two trailing newlines. If this is not allowed, a trailing `¨` or `?` could be added so it'll output a single trailing newline instead.

Try it online or verify all test cases.

**Explanation:**

*Step 1: Prepare the input character-list by joining by `-` and adding additional trailing `-`. Then use the (modifiable) Canvas builtin to put this string itself and all spaces at the correct positions in the output rectangle:*

```
LR·<€D¬š         # Create the list of lengths for the Canvas builtin:
L                #  Push a list in the range [1, first (implicit) input-integer]
 R               #  Reverse it to range [n,1]
  ·              #  Double each inner value
   <             #  Decrease each by 1
    €D           #  Duplicate each value within the list
      ¬š         #  And prepend an additional copy of the first/largest item
Iõ¹·nи«'-ý      '# Create the string to draw for the Canvas builtin:
I                #  Push the second input-list of characters
  ¹·n            #  Push the first input, double it, take the square of that: 4n²
 õ   и           #  Create a list with that many empty strings ""
      «          #  Append it to the input-list
       '-ý      '#  Join this list with "-" delimiter
Ž9¦S             # Create the list of directions for the Canvas builtin:
Ž9¦              #  Push compressed integer 2460
   S             #  Convert it to a list of digits: [2,4,6,0]
.Λ               # Use the (modifiable) Canvas builtin with these three options
¶¡ιн»            # Remove all (0-based) odd-indexed rows
¶¡               # Split it on newlines
  ι              # Uninterleave it into two parts
   н             # Pop and only leave the first part
    »            # Join it back together by newlines

```

Try just step 1 online.

For more information on how the Canvas builtin works, see this 05AB1E tip of mine.
See this 05AB1E tip of mine (section *How to compress large integers?*) to understand why `Ž9¦` is `2460`.

*Step 2: Replace all `-` that are currently at edge or corner positions with `|`:*

```
¶«               # Append a trailing newline
„ -              # Push string " -"
   Â             # Bifurcate, short for Duplicate & Reverse copy: "- "
    ‚            # Pair them together: [" -","- "]
     D           # Duplicate it
      ð¶:        # Replace all spaces with newlines in the copy: ["\n-","-\n"]
         «       # Merge the two together: [" -","- ","\n-","-\n"]
D                # Duplicate it
 '-'|:           # Replace all "-" with "|" in the copy: [" |","| ","\n|","|\n"]
:                # Replace all [" -","- ","\n-","-\n"] respectively with
                 # [" |","| ","\n|","|\n"]

```

Try the first two steps online.

*Step 3: Replace all `|` at corner positions with either `.` (for the top halve) or `'` (for the bottom halve):*

```
2ä               # Split the string into two equal-sized parts
  ε              # Map over both parts:
   „|-           #  Push string "|-"
      Â‚         #  Bifurcate and pair again: ["|-","-|"]
   D             #  Duplicate it
    '|     :    '#  Replace all "|" with the following in the copy:
      „.'Nè     '#   The map-index'th character of string ".'"
   :             #  Replace all ["|-","-|"] respectively with
                 #  [".-","-."] for the first iteration of the map
                 #  or ["'-","-'"] for the second iteration of the map

```

Try the first three steps online.

*Step 4: And finally, fix the `>` or `<`*, and output the result:

```
    i            #   If
¹N+              #   the first input + the (0-based) map-index
   É             #   is odd:
     Ni          #    If it's the second iteration of the map:
       '' '<.;  '#     Replace the first "'" with "<"
      ë          #    Else (it's the first iteration of the map)
       ¨         #     Remove the last character of the first part
        '>«     '#     And append a ">" instead
]                # Close both if-statements and the map
 J               # Join the two modified parts back together
                 # (after which the result is output implicitly with trailing newline)

```

# Answer
> 1 votes
# Haskell, ~~333~~ 289 bytes

```
f s n=h s n 0 0$concatMap(++"\n").g$n
h(c:t)n d z m=take z l++c:drop(z+1)l where e=mod(d+sum[1|a<-".'",m!!z==a])4;l=h t n e(z+2*[1,n,-1,-n]!!e)m
h _ _ _ _ m=m
g 1=[">"]
g 2=["--.","<-'"]
g n=(m++"--."):(map(++" |").h)b++["'-"++m++"'"]where b=g(n-2);m=b>>"--";h(l:k)=[".-"++l]++map("| "++)k

```

Try it online!

Function `g` makes an empty snake as a list of strings. Function `h` fills in the given string `s` while converting the list of strings to a single string. Function `f` is the resulting target function.

In function `h`, `d` is the direction where to go for the next character of string `s` and `z` is the position of the character to replace.

# Answer
> 1 votes
# Java (JDK), ~~279~~ ~~278~~ 276 bytes

```
char[]f(String s,int n){var a=g(n).toCharArray();int z=0,d=0;for(var c:s.toCharArray()){d+=a[z]/2&1;a[z]=c;z+=(d%2<1?1:n)*(d%4<2?2:-2);}return a;}String g(int n){String m;return n>1?(m="--".repeat(n-2))+"--.\n"+(n>2?".-"+g(n-2).replace("\n"," |\n| ")+" |\n'"+m:"<")+"-'":">";}

```

Try it online!

I have derived this from my JavaScript answer. Java is not really good for code golf, but I think, the result is not too bad.

* minus 3 bytes, thanks to ceilingcat

---
Tags: code-golf, string, ascii-art
---


title: 4D rotation matrix to quaternions

text:
# Question
Title: 4D rotation matrix to quaternions
It is well-known that a 3D rotation can always be represented by a quaternion. It is less well-known that a *4D* rotation can always be represented by *two* quaternions, sending a point \\$p=(a,b,c,d)^T\\$ represented as the quaternion \\$a+bi+cj+dk\\$ to the point \\$p'=xpy\\$ for an appropriate choice of unit quaternions \\$x,y\\$.

Let \\$R\\$ be a 4D rotation matrix. Then the corresponding \\$x,y\\$ can be obtained through a direct algorithm of Perez-Gracia and Thomas:

* Compute \\$S=\frac{R-A\_1RA\_1-A\_2RA\_2-A\_3RA\_3}4\\$ where $$A\_1=\begin{bmatrix}0&0&0&-1\\0&0&-1&0\\0&1&0&0\\1&0&0&0\end{bmatrix}$$ $$A\_2=\begin{bmatrix}0&0&1&0\\0&0&0&-1\\\-1&0&0&0\\0&1&0&0\end{bmatrix}$$ $$A\_3=\begin{bmatrix}0&-1&0&0\\1&0&0&0\\0&0&0&-1\\0&0&1&0\end{bmatrix}.$$
* Set \\$Y=\frac S{(\det S)^{1/4}}\\$ and \\$X=RY^T\\$. We have \\$R=XY\\$, where \\$X\\$ and \\$Y\\$ are the matrices of *left- and right-isoclinic rotations* respectively – very special matrices with at most four distinct magnitudes among their entries.
* Finally \\$x\\$ and \\$y\\$ are the left-most columns of \\$X\\$ and \\$Y\\$. The pair \\$(-x,-y)\\$ also corresponds to \\$R\\$, analogous to the 3D case.

\\$S\\$ above may have zero determinant, in which case one of the following alternative expressions should be used. These of course give different \\$S\\$ matrices, but the steps afterwards are unchanged: $$S=-\frac14(RA\_1+A\_1R+A\_3RA\_2-A\_2RA\_3)$$ $$S=-\frac14(RA\_2+A\_2R+A\_1RA\_3-A\_3RA\_1)$$ $$S=-\frac14(RA\_3+A\_3R+A\_2RA\_1-A\_1RA\_2)$$

## Task

Given \\$R\\$ – an orthogonal (to floating-point error) 4×4 real matrix with determinant 1 – output a corresponding \\$(x,y)\\$ pair to within \\$10^{-6}\\$ entrywise relative error. You may use any reasonable and consistent formats for input and output, and any correct formula for the calculation (including the one in the previous section).

This is ; fewest bytes wins.

## Test cases

These are in the format \\$R\to x\ y\\$. The random cases were generated (and you can generate your own random cases) with this program.

```
[[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]] -> [1.0, 0.0, 0.0, 0.0] [1.0, 0.0, 0.0, 0.0]
[[-1, 0, 0, 0], [0, -1, 0, 0], [0, 0, -1, 0], [0, 0, 0, -1]] -> [1.0, 0.0, 0.0, 0.0] [-1.0, 0.0, 0.0, 0.0]
[[0, 0, 1, 0], [0, 0, 0, 1], [0, 1, 0, 0], [1, 0, 0, 0]] -> [1.0, 0.0, 0.0, 0.0] [0.0, 0.0, -1.0, 0.0]
[[0, 0, 1, 0], [-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, -1]] -> [0.5, 0.5, 0.5, -0.5] [-0.5, -0.5, -0.5, -0.5]
[[0, 0, 0, -1], [1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]] -> [0, -0.7071067811865476, 0, -0.7071067811865476] [-0.7071067811865476, 0, 0.7071067811865476, 0]
[[-0.6609058926555349, -0.30938449301078536, -0.6536493902436745, -0.2005669742797215], [-0.19737145221236216, 0.6931746532606626, 0.08266116424964398, -0.6882735952028355], [0.13703192282789176, -0.6502921800262064, 0.3686714537074865, -0.6499412988447983], [0.7109642487712476, 0.030169788832262925, -0.6557369638659809, -0.25224721015459695]] -> [0.560009784749661, 0.400037446835586, 0.272063553490942, 0.6725626401873549] [0.06637964559158858, 0.052592253308694104, 0.6737046111530368, 0.7341320688092741]
[[0.6544007065477859, -0.5813716570041381, -0.411235410397809, -0.2542678684713569], [0.6193101080207767, 0.7694074810291105, -0.005562224168405557, -0.1563207596643309], [0.38183012824424395, -0.12606111825246455, 0.23940297340390976, 0.8837423628837136], [-0.2059622745505508, 0.23265364607854452, -0.8795116345009956, 0.36043183434001774]] -> [0.9455738853169363, -0.26286929698266226, 0.18881691258838904, -0.033733271870118764] [0.5350303732855687, 0.7836340999984829, 0.31251919145079116, 0.044630168680125246]

```

---

This question and its 3D version were inspired by my answer to a MathsSE question. I needed to wrestle with 4D rotations when rendering images like these for this other MathsSE question which I have asked, and for which I have no answers:

# Answer
> 1 votes
# Itr, 194 bytes

```
$R(0ää1~,0ä1~0,0 1áä,1 0ää)$A(0ä1á,0ää1~,1~0ää,0 1áä)$B(0 1~0ä,1 0ää,0ää1~,0ä1á)$C(RARA**-BRB**-CRC**-4÷RA*AR*+CRB**+BRC**-4÷~RB*BR*+ARC**+CRA**-4÷~RC*CR*+BRA**+ARB**-4÷~)äa¿×èäarr÷$Y(YRT*YT)µ0@

```

with newlines for readability:

```
$R
(0ää1~,0ä1~0,0 1áä,1 0ää)$A
(0ä1á,0ää1~,1~0ää,0 1áä)$B
(0 1~0ä,1 0ää,0ää1~,0ä1á)$C
(
 RARA**-BRB**-CRC**-4÷
 RA*AR*+CRB**+BRC**-4÷~
 RB*BR*+ARC**+CRA**-4÷~
 RC*CR*+BRA**+ARB**-4÷~
)
äa¿×è
äarr÷$Y
(YRT*YT)µ0@

```

input as matrix, output as pair of lists

*For some test-cases \\$(-x,-y)\\$ is returned instead*

online interpreter

version taking nested arrays as input

## Explanation

Straight forward implementation of the algorithm in the question:

```
®                           ; convert (implicit) input to matrix (makes it easier to use the test cases)
$R                          ; store input in R
(0ää1~,0ä1~0,0 1áä,1 0ää)$A ; matrix A1 (0 1 -> literals, ä -> dup, ~ -> negate, á -> over)
(0ä1á,0ää1~,1~0ää,0 1áä)$B  ; matrix A2
(0 1~0ä,1 0ää,0ää1~,0ä1á)$C ; matrix A3
(                           ; array containing the three possibilities for S
 RARA**-BRB**-CRC**-4÷
 RA*AR*+CRB**+BRC**-4÷~
 RB*BR*+ARC**+CRA**-4÷~
 RC*CR*+BRA**+ARB**-4÷~
)
                            ; get all elements of the array with non-zero determinant:
äa                          ; vector of determinants of the elements
  ¿                         ; is nonzero (vectorized)
   ×                        ; repeat elements of array that many times, picks elements satisfying condition
è                           ; get the first element of that array "S"
äarr÷$Y                     ; compute Y ( S/ sqrt(sqrt(det( S ))))
(YRT*YT)                    ; pair containing X^T=Y*R^T and Y^T
µ0@                         ; replace elements with their first row (get first column of X and Y)

```

---
Tags: code-golf, math, geometry, matrix, rotation
---


title: Find the temperature closest to 0

text:
# Question
Title: Find the temperature closest to 0
In this exercise, you have to analyze records of temperature to find the closest to zero.

Write a program that prints the temperature closest to 0 among input data.

## Input

* N, the number of temperatures to analyse (optional). This will be nonzero.
* The N temperatures expressed as integers ranging from *-273 to 5526*.

## Output

Output the temperature closest to 0. If two temperatures are equally close, take the positive one. For instance, if the temperatures are -5 and 5, output 5.

## Example

```
Input

    5
    1 -2 -8 4 5

Output

    1

```

This challenge is similar to this one on CodinGame, you can view the problem statement source here. Some modifications have been made to the text.

# Answer
> 10 votes
# Python, 35 bytes

```
lambda l:max((-x*x,x)for x in l)[1]

```

Try it online!

Narrowly beats:

```
lambda l:min(l,key=lambda x:2*x*x-x)
lambda l:min(sorted(l)[::-1],key=abs)

```

# Answer
> 9 votes
## JavaScript (ES6), 33 bytes

```
a=>a.reduce((m,n)=>n*n-n<m*m?n:m)

```

### Demo

```
let f =

a=>a.reduce((m,n)=>n*n-n<m*m?n:m)

console.log(f([1, -2, -8, 4, 5]))
```

# Answer
> 5 votes
# Jelly, 4 bytes

```
AÐṂṀ

```

Try it online!

### How it works

```
AÐṂṀ  Main link. Argument: A (array)

AÐṂ   Take all elements with minimal absolute value.
   Ṁ  Take the maximum. Yields 0 for an empty list.

```

# Answer
> 4 votes
# Brachylog (2), 5 or 2 bytes

```
~{≜∈}

```

Try it online!

It wouldn't surprise me if there were a shorter solution along the lines of the Jelly or Pyke, but I like this one because it's so weird.

This is simply Brachylog's "find a list containing the input" operator , with an evaluation strategy  that simply tries explicit values for integers until it finds one that works (and it happens to try in the order 0, 1, -1, 2, -2, 3, etc., which is surprisingly handy for this problem!), and inverted `~` (so that instead of trying to find an output list containing the input, it's trying to find an output contained in the input list). Unfortunately, inverting an evaluation strategy along with the value itself costs 2 bytes, so this doesn't beat the Jelly or Pyke solutions.

There's also a dubious 2-byte solution `≜∈`. All Brachylog predicates take exactly two arguments, which can each be inputs or outputs; by convention, the first is used as an input and the second is used as an output, but nothing actually enforces this, as the caller has complete control over the argument pattern used (and in Prolog, which Brachylog compiles to, there's no real convention about argument order). If a solution which takes input through its second argument and produces output through its first argument is acceptable, there's no requirement to do the inversion.

# Answer
> 4 votes
# , 31 bytes

```
(l=scan())[order(abs(l),-l)][1]

```

Try it online!

# Answer
> 2 votes
## Pyke, 4 bytes

```
S_0^

```

Try it online!

```
S_   - reversed(sorted(input))
  0^ - closest_to(^, 0)

```

# Answer
> 2 votes
# MATL, ~~9~~ 6 bytes

```
0iSPYk

```

Try it online!

Thanks to Luis Mendo for pointing out there's actually a built-in for this in MATL, which is not present in MATLAB.

```
 i     % Take input
  S    % Sort
   P   % Reverse to have largest value first.
0   Yk % Closest value to zero, prioritizing the first match found

```

If you wish to follow the spec and also provide the number of temperatures to be read, this should be given as the second input, and will be silently discarded.

# Answer
> 2 votes
# Mathematica, ~~21~~ 19 bytes

```
Max@*MinimalBy[Abs]

```

Composition of functions. Takes a list of integers as input and returns an integer as output.

# Answer
> 2 votes
# C++14, 64 bytes

As unnamed lambda, expecting first argument to be like `vector<int>` and returing via reference parameter.

```
[](auto L,int&r){r=L[0];for(int x:L)r=x*x<=r*r?r+x?x:x>r?x:r:r;}

```

Ungolfed and usage:

```
#include<iostream>
#include<vector>

auto f=
[](auto L,int&r){
  r=L[0];
  for(int x:L)
    r = x*x<=r*r ?   //x is absolute less or equal
      r+x ?          //r==-x?
        x :          //no, just take x
        x>r ?        //take the positive one
          x :
          r      :
      r              //x was absolute greater, so keep r
    ;
}
;

int main(){
 std::vector<int> v = {5, 2, -2, -8, 4, -1, 1};
 int r;
 f(v,r);
 std::cout << r << std::endl;
}

```

# Answer
> 2 votes
# Japt `-g`, 3 bytes

```
ña¼

```

Try it online!

# Japt, 5 bytes

```
ña¼ v

```

Try it online!

# Answer
> 2 votes
# Perl 5 `-p`, 21 bytes

Added `+1` for `-p` since this challenge precedes "options don't count"

```
$G[abs]=$_}{$_+="@G"

```

Try it online!

# Answer
> 1 votes
# 05AB1E, 16 bytes

```
Îåà_Di¹{RDÄßs\kè

```

Explanation:

```
Î                 Push 0 and [implicit] input array
 å                For each element in the array, is it a 0?
  à               Find the greatest value (1 if there was a 0 in it, 0 otherwise)
   _              Negate boolean (0 -> 1, 1 -> 0)
    D             Duplicate
     i            If true, continue
      ¹           Push input
       R          Reversed
        D         Duplicated
         Ä        Absolute value
          ß       Greatest element
           s      Swap top two values in stack
            \     Delete topmost value in stack
             k    Index of greatest element in the array
              è   Value of the index in the input array

```

Try it online!

Not at short as I'd like, but at least it works.

# Answer
> 1 votes
## Haskell, 29 bytes

```
snd.maximum.map(\x->(-x^2,x))

```

Usage example: `snd.maximum.map(\x->(-x^2,x)) $ [1,-2,-8,4,5]`-\> `1`.

Map each element `x` to a pair `(-x^2,x)`. Find the maximum and pick the 2nd element from the pair.

# Answer
> 1 votes
# Java 8, ~~63~~ 39 bytes

```
s->s.reduce(1<<15,(r,i)->r*r-r<i*i?r:i)

```

Port from *@Arnauld's* JavaScript answer. I couldn't find anything shorter..

-10 bytes converting Java 7 to 8,
and another -24 bytes thanks to *@OlivierGrégoire*.

**Explanation:**

Try it online.

```
s->                   // Method with IntStream parameter and int return-type
  s.reduce(1<<15,     //  Start `r` at 32768 (`32768^2` still fits inside a 32-bit integer)
     (r,i)->r*r-r<i*i?//  If `r^2 - r` is smaller than `i^2`:
       r              //   Leave `r` the same
      :               //  Else:
       i)             //   Replace the current `r` with `i`
                      //  Implicitly return the resulting `r`

```

# Answer
> 1 votes
# PHP, 81 bytes

two solutions: the first one requires an upper bound; both require all temperatures nonzero.

```
for($r=9e9;$t=$argv[++$i];)abs($t)>abs($r)|abs($t)==abs($r)&&$t<$r?:$r=$t;echo$r;
for(;$t=$argv[++$i];)$r&&(abs($t)>abs($r)|abs($t)==abs($r)&&$t<$r)?:$r=$t;echo$r;

```

Run with `-r`, provide temperatures as command line arguments.

A lazy solution for **92 bytes**:

```
$a=array_slice($argv,1);usort($a,function($a,$b){return abs($a)-abs($b)?:$b-$a;});echo$a[0];

```

defines a callback function for `usort` and uses it on a slice of `$argv`.

# Answer
> 1 votes
# Perl 6, 15 bytes

```
*.min:{.²,-$_}

```

Try it online!

# Answer
> 1 votes
# JavaScript (Node.js), 30 bytes

```
a=>a.sort((a,b)=>a*a-a>b*b)[0]

```

Try it online!

# Answer
> 1 votes
# Octave, 28 bytes

```
@(x)max(x(min(a=abs(x))==a))

```

Try it online!

Finds the smallest absolute value (`min(a=abs(x))`), then maps it back to which elements have that smallest absolute value in case of a tie (`x(...==a)`). Finally takes the maximum value of the results (`max(...)`) to ensure that in the event of a tie we get one result which is the positive one.

# Answer
> 1 votes
## PHP, 209 Bytes

**Not really golfed**, but wanted to try to use mostly array functions, avoiding loops

Try it Online!!

**Code**

`function f($a){$a[]=0;sort($a);$k=array_search(0,$a);$o=array_slice($a,$k+1);$u=array_reverse(array_diff($a,$o));if($u[1]&&$o[0]){$r=(abs($u[1])<abs($o[0]))?$u[1]:$o[0];}else{$r=($u[1])?$u[1]:$o[0];}return$r;}`

**Explanation**

```
function f($a){
$a[]=0;                                #As all nonzero values, 0 is pushed
sort($a);                              #Sorting the array
$k=array_search(0,$a);                 #Search where zero is
$o=array_slice($a,$k+1);               #Array with all values >0
$u=array_reverse(array_diff($a,$o));   #Array with all smaller than zero values
                                       #Array has ascending order so it gets reversed
if($u[1]&&$o[0]){                      #if both are set we just compare the abs value
    $r=(abs($u[1])<abs($o[0]))?$u[1]:$o[0];
}else{
    $r=($u[1])?$u[1]:$o[0];            #al least one of them will allways be set
                                       #the first value is always returned
                                       #the 0 value on $u is not usetted that why $u[1]
}
return $r;
}

```

# Answer
> 1 votes
# Julia 0.6, 29 bytes

```
x->sort(x,by=x->abs(x-.1))[1]

```

Sort by the absolute value of the temperature, but subtract .1 first to ensure positive temperatures always win.

Try it online!

# Answer
> 1 votes
# 05AB1E, 5 bytes

```
{R0.x

```

Try it online.

Or alternatively:

```
ÄWQÏà

```

Try it online.

**Explanation:**

```
{      # Sort the (implicit) input-list lowest-to-highest
 R     # Reverse it to highest-to-lowest
  0.x  # Pop and push the item closest to 0
       # (after which the result is output implicitly)

Ä      # Get the absolute value of each in the (implicit) input-list
 W     # Push the minimum (without popping the list)
  Q    # Check which are equal to this minimum
   Ï   # Only keep the values in the (implicit) input-list at the truthy indices
    à  # Pop and push the maximum of the remaining values
       # (after which the result is output implicitly)

```

# Answer
> 1 votes
# Thunno 2 `h`, 4 bytes

```
ṠrþA

```

Try it online!

#### Explanation

```
ṠrþA  # Implicit input
Ṡr    # Reverse-sort
  þA  # Sort by |x|
      # Take the first item
      # Implicit output

```

# Answer
> 1 votes
# Vyxal `G`, 20 bitsv2, 2.5 bytes

```
⁽ȧP

```

Try it Online!

Finds the minimum in the list by absolute value

# Answer
> 0 votes
# Python, 62 bytes

```
def f(n):
    r=min(map(abs,n))
    return r if r in n else -r

```

It feels like there is a much simpler/shorter solution.

# Answer
> 0 votes
# C (clang), 74 bytes

```
k,m;f(*i,n){for(k=*i;--n>0;k=(k*k>m*m||(k==-m&&k<m))?m:k)m=i[n];return k;}

```

Try it online!

# Answer
> 0 votes
# Stax, 6 bytes

```
¢M║⌠§☺

```

Run and debug it at staxlang.xyz!

### Unpacked (6 bytes) and explanation

```
{|a}eoH
{  }e      Get all elements of array producing the minimum value from a block.
 |a          Absolute value.
     o     Sort ascending.
      H    Take last. Implicit print.

```

# Answer
> 0 votes
# Pyth, 4 bytes

```
.m.a

```

Try it online!

Explanation:
```
.m.a   #Code
.m.abQ #With implicit variables
.m   Q #Filter input list for values b with minimal value of the following:
  .ab  #Absolute value of b

```

# Answer
> 0 votes
# Python 3, 31 bytes

```
a=lambda q:sorted(q,key=abs)[0]

```

Try it online!

Sorts items by absolute value and prints the first element.

# Answer
> 0 votes
# SmileBASIC, 56 bytes

```
DEF Z N,T
RSORT T
DIM V[N]ARYOP 2,V,T,T
SORT V,T?T[0]END

```

First, the input list is sorted, so the positive temperature will be chosen if there's a tie. Then each temperature is squared and stored in another array. The original array is sorted by this array, and the first item is printed.

# Answer
> 0 votes
# Avail, 88 bytes

```
Method"f_«_»"is[c:[1..∞),t:integer*|quicksort a,b in t[1..c] by[|a-0.1|<|b-0.1|][1]]

```

Approximate deobfuscation:

```
Method "nearest to zero among first _ of «_»" is
[
    count : natural number,
    temps : integer*
|
    (quicksort a, b in temps[1..count] by [|a-0.1| < |b-0.1|])[1]
]

```

The pattern syntax in the method's name, `f_«_»`, will read the initial count as a natural number (whose type is abbreviated above as the range type `[1..∞)`) separate from the collected tuple of subsequent integers.

All that remains for the body is to sort by a custom comparator. Here we escape the need for a second-level comparison between `x` and `-x` by shifting the values slightly towards -∞.

# Answer
> 0 votes
# dc, 53 bytes

```
Fd^sr[d*v]sA[ddlr+0=Asr]sR[dlAxlrlAx!<Rs_z0<M]dsMxlrp

```

Try it online!

We're going to use the register `r` to hold our final result, so the first thing we need to do is put a too-big number in there so that our first comparison always succeeds. I think the largest number we can push in two bytes is 165 (which is less than the required 5526), but `Fd^` gives us 15^15 which is plenty large. Macro `A`, `[d*v]sA` just does the square root of the square to give us absolute value.

Macro `R` handles putting a value into register `r`; we'll come back to it in a second. Macro `M`, `[dlAxlrlAx!<Rs_z0<M]dsMx` is our main macro. Duplicates the value on the stack, runs `A` to get ABS, then pushes the value in `r` and does the same. `!<R` checks to see if ABS(`r`) is ~~greater than or equal to~~ not less than ABS(top of stack), and if so it runs `R`. Since we had to leave behind a copy of the original top of stack for `R` to potentially use, we store to a useless register (`s_`) to pop it. `z0<M` just loops `M` until the stack is empty.

Macro `R`, `[ddlr+0=Asr]sR` duplicates the top of stack twice (we need to leave something behind for `M` to gobble up when we return). At this point we know that of the two absolute values, our new value is less than or equal to our old value. If they're equal, and one is positive and the other is negative, we always need the positive. Fortunately, knowing this we can easily check for the case of one being the inverse of the other by simply adding them and comparing to 0. If so, we run `A`, and no matter what else happened we know we're storing whatever is left in `r`.

After `M` has gone through the whole stack, we `l`oad `r` and `p`rint it.

# Answer
> 0 votes
# Octave, 19 bytes

```
@(x)min(complex(x))

```

**Try it online!**

This exploits the fact that `min` with complex input compares by absolute value, then by angle:

> For complex arguments, the magnitude of the elements are used for comparison. If the magnitudes are identical, then the results are ordered by phase angle in the range (-pi, pi\].

# Answer
> 0 votes
# C#, 171 bytes

```
using static System.Console;using System.Linq;class s{static void Main()=>Write(ReadLine()=="0"?0:ReadLine().Split(' ').Select(int.Parse).OrderBy(v=>v*(.1-v)).Last());}

```

Try it online!

# Answer
> 0 votes
# Headass, 56 bytes

```
O{ON-)+E:U}.U+OUO[{UO(])P:N(+)+E:}.UO[U-O{UO(])P:N(+)E:}

```

Try It Online!

Increments / decrements a pair of counters until the value of the counter matches one of the inputs, with the positive counter having the first go (after 0 of course) to prioritize it over negative answers.

Positive counter hereby referred to as `+counter` and negative counter as `-counter`

Code breakdown:

```
O{ON-)+E:U}.  code block 0
O O           initialize both counters to 0
 {ON-)  :U}   put all inputs on the queue
      +E      then move to code block 1
           .  end code block

U+OUO[{UO(])P:N(+)+E:}.  code block 1 (-counter, starting at 0)
U+O                      increment +counter and put back on queue
   UO[                   store 0/-counter to r2 and put back on queue
      {       N(+)  :}   for each input
       UO                  enqueue input
         (])               if input is equal to 0/-counter
            P:               print value and halt
                  +E     then go to code block 2
                      .  end code block

UO[U-O{UO(])P:N(+)E:}    code block 2 (+counter, starting at 1)
UO[                      store +counter to r2 and put back on queue
   U-O                   decrement -counter and put back on queue
      {       N(+) :}    for each input
       UO                  enqueue input
         (])               if input is equal to +counter
            P:               print value and halt
                  E      then go to code block 1

```

I tried doing this with only 2 code blocks, 1 to init and one to handle both counters, but that meant that whichever value came first between positive and negative would win, which is wrong. There might be additional logic that could be added to such a loop which, combined with some more logic-golfing, could be shorter than this version, but i still think its pretty good.

# Answer
> 0 votes
# J-uby, 12 bytes

```
:min_by+:abs

```

Attempt This Online!

# Answer
> 0 votes
# APL (Dyalog Unicode), 16 bytes

```
{⌈/⍵/⍨a=⌊/a←|¨⍵}

```

Try it on TryAPL.org!

---
Tags: code-golf
---


title: Scrabble scorer

text:
# Question
Title: Scrabble scorer
### Challenge:

Take a string of upper or lower case letters as input (optional), and calculate the score that string would get in a game of Scrabble in English.

### Rules:

The score of each letter is as follows (use this even if there are other versions of the game):

```
1 point: E, A, I, O, N, R, T, L, S, U
2 points: D, G
3 points: B, C, M, P
4 points: F, H, V, W, Y
5 points: K
8 points: J, X
10 points: Q, Z

```

The score of a string is simply the sum of the scores of each of the letters used. You may assume that you have plenty of tiles available, so long words, and words with many of the same letters are valid input.

### Test cases:

```
ABC       ->    7
PPCG      ->   11
STEWIE    ->    9
UGPYKXQ   ->   33
FIZZBUZZ  ->   49
ABCDEFGHIJKLMNOPQRSTUVWXYZ  -> 87

```

The shortest answer in each language wins! The input and output formats are flexible, so you may take the input as an array of characters (upper or lower case) if you want.

# Answer
> 20 votes
# sed 4.2.2, 81

```
s/[QZ]/JD/g
s/[JX]/KB/g
s/K/FE/g
s/[FHVWY]/BE/g
s/[BCMP]/DE/g
s/[DG]/EE/g
s/./1/g

```

Output is in unary.

Reduces each letter to a combination of lower-scoring letters until all letters are 1-scorers. Then replaces those with `1`s to give a unary count.

Try it online!

# Answer
> 11 votes
# Octave, 50 bytes

```
@(t)'				'/3*sum(65:90==t')'

```

Try it online!

Challenge accepted. Explanation:

```
@(t)             % Define anonymous function taking a single argument t.
    ' ... '/3    % Row vector with letter scores. Corresponds to char([1 3 3 2 ...]*3).
                 % The factor 3 was necessary to avoid a newline.

*                % Dot product (yes, * is dot product, .* is not. Go figure). Equivalent to sum of element-wise products.
     65:90       % Alphabet
          ==t'   % Broadcast equality with input string.
 sum(         )  % Sum this matrix. Gives the count of each letter in the alphabet
               ' % Transpose into column vector for dot product

```

# Answer
> 10 votes
# Haskell, ~~86~~ 84 bytes

```
f s=length s+sum[n|x<-s,(n,y)<-zip(9:7:[1..])$words"QZ JX DG BCMP FHVWY K",x`elem`y]

```

Try it online!

### Explanation

Most letters give a score of 1 and thus we don't need to keep track of these, instead we just decrement each score (saves 1 byte on `10` as well) and then add the length of the string to the resulting score.

Thanks @nimi for -2 bytes (rearanging the words and using `[1..]` instead of `[4,3..]`)!

# Answer
> 10 votes
# Beatnik, 733 bytes

Since it really had to be done, here it is. It was a really nasty to debug and provided a few challenges.

Input must be uppercase letters only. Output is unary (hope that is OK?)

```
J K ZZZZZZK Z ZD ZB ZZZZZZZZZZZZZZZZZA K A Z ZD ZB ZZZZZZZZZZZZZZZKF K A Z ZD ZB ZZZZZZZZZZZZZZZB K A Z ZD ZB ZZZZZZZZZZZZZZZ K A Z ZD ZB ZZZZZZZZZZZZZZKD K A Z ZD ZB ZZZZZZZZZZZZZD K A Z ZD ZB ZZZZZZZZZZZZZD K A Z ZD ZB ZZZZZZZZZZZZ K A Z ZD ZB ZZZZZZZZZZZZB K A Z ZD ZB ZZZZZZZZZKA K A Z ZD ZB ZZZZZZZZZKF K A Z ZD ZB ZZZZZZZZZZK K A Z ZD ZB ZZZZZZZZZB K A Z ZD ZB ZZZZZZZZZB K A Z ZD ZB ZZZZZZZZKD K A Z ZD ZB ZZZZZZZK K A Z ZD ZB ZZZZKB K A Z ZD ZB ZZZZZZKF K A Z ZD ZB ZZZZZZB K A Z ZD ZB ZZZZZFB K A Z ZD ZB ZZZZZA K A Z ZD ZB ZZZAK K A Z ZD ZB ZZZ K A Z ZD ZB ZD K A Z ZD ZB ZKB K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K ZZZZKF KF K A ZKA ZZZZZZZZZZZZZZZZZZY

```

Try it online!

General process is:

* get character from input
* subtract 65
* check if result is 0
    + if 0 jump specified amount of words.
    + otherwise subtract 1 and repeat check.
* the jump targets are push print operations followed be a loop back to beginning of program.

Ends with an error.

A more complete explanation:

```
J K ZZZZZZK Z ZD               # Get input and subtract 65
ZB ZZZZZZZZZZZZZZZZZA K A Z ZD # Character A - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZZZKF K A Z ZD  # Character B - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZZZB K A Z ZD   # Character C - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZZZ K A Z ZD    # Character D - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZZKD K A Z ZD   # Character E - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZD K A Z ZD     # Character F - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZZD K A Z ZD     # Character G - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZ K A Z ZD       # Character H - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZZZB K A Z ZD      # Character I - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZKA K A Z ZD        # Character J - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZKF K A Z ZD        # Character K - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZZK K A Z ZD        # Character L - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZB K A Z ZD         # Character M - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZZB K A Z ZD         # Character N - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZZKD K A Z ZD         # Character O - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZZK K A Z ZD           # Character P - if 0 jump to print, otherwise subtract 1
ZB ZZZZKB K A Z ZD             # Character Q - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZKF K A Z ZD           # Character R - if 0 jump to print, otherwise subtract 1
ZB ZZZZZZB K A Z ZD            # Character S - if 0 jump to print, otherwise subtract 1
ZB ZZZZZFB K A Z ZD            # Character T - if 0 jump to print, otherwise subtract 1
ZB ZZZZZA K A Z ZD             # Character U - if 0 jump to print, otherwise subtract 1
ZB ZZZAK K A Z ZD              # Character V - if 0 jump to print, otherwise subtract 1
ZB ZZZ K A Z ZD                # Character W - if 0 jump to print, otherwise subtract 1
ZB ZD K A Z ZD                 # Character X - if 0 jump to print, otherwise subtract 1
ZB ZKB                         # Character Y - if 0 jump to print, otherwise subtract 1
K ZZZZKF KF                    # Jump Point for print 1111111111
K ZZZZKF KF                    #
K ZZZZKF KF                    # Jump Point for print 11111111
K ZZZZKF KF                    #
K ZZZZKF KF                    #
K ZZZZKF KF                    # Jump Point for print 11111
K ZZZZKF KF                    # Jump Point for print 1111
K ZZZZKF KF                    # Jump Point for print 111
K ZZZZKF KF                    # Jump Point for print 11
K ZZZZKF KF                    # Jump Point for print 1
K A ZKA ZZZZZZZZZZZZZZZZZZAAAA # Jump back to start

```

# Answer
> 8 votes
# Pyth, 40 bytes

```
sm+2x.e}dbc." zØÍ jÙ¹>;%OG5§"\ 1

```

Try it here

### Explanation

```
sm+2x.e}dbc." zØÍ jÙ¹>;%OG5§"\ 1
 m                              Q  For each character in the (implicit) input...
    x.e  b                     1   ... find the first index in...
          c." zØÍ jÙ¹>;%OG5§"\     ['dg','bcmp','fhvwy','k','','','jx','','qz']
       }d                          ... containing the character...
  +2                               ... 2-indexed.
s                                  Take the sum.

```

# Answer
> 8 votes
# Brain-Flak, ~~210, 204, 198, 184~~, 170 bytes

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

```

Try it online!

Thanks to @JoKing for saving 14 bytes!

Readable version:

```
({              # For each character

                # Push array of letter scores
                # Also adjust character to 1-indexing
        <([{}]<>
        (({}{}))    # Push 2 0s
        (([][][][][])   # 10
        <((([]())   # 4
        <([][])>    # 8
        ))      # 4,4
        ((((()))))> # 1,1,1,1
        )       # 10
        []      # Add 12 to difference
        (((()()())  # 3
        <((()))>    # 1,1
        )       # 3
        ((())()()()())) # 1, 5
        ((())()()())    # 1, 4
        ((()())()())    # 2, 4
        []      # Add 22 to difference
        ((((())())()))  # 1,2,3
        (())        # 1
        )   # Push 65-char

        {({}<{}>())} # Index character into score array
        >
        {}{}         # Add score to running total
        <{{}}><>     # Clear the stack

})               # Implicit print of total score

```

# Answer
> 7 votes
# Python 2, 78 bytes

```
lambda x:sum(map(('ABCEIKLMNOPRSTU'+'BCDGMPQZ'*2+'FHJJKQQVWXXYZZ'*4).count,x))

```

Try it online!

### Shorter version, port of DanielIndie's answer, ~~71~~ 70 bytes

-1 byte thanks to Sunny Patel

```
lambda x:sum(int('02210313074020029000033739'[ord(c)-65])+1for c in x)

```

Try it online!

# Answer
> 7 votes
# JavaScript (Node.js), 71 66 63 62 bytes

* @Arnauld awesome as always reducing 7 bytes
* thanks to l4m2 for rducing by 1 byte

```
s=>Buffer(s).map(x=>s="02210313074020029000033739"[x-65]-~s)|s

```

Try it online!

# Answer
> 7 votes
# Java 8, ~~75~~ ~~71~~ 70 bytes

```
s->s.chars().map(c->"\n\n".charAt(c-65)).sum()
```

-1 byte by changing `"02210313074020029000033739".charAt(c-65)-47` to unprintables (and two `\n`) so the `-47` can be removed. Inspired by @Sanchises' Octave answer.

Try it online.

```
s->          // Method with String parameter and integer return-type
  s.chars()  //  Loop over the characters as IntStream
   .map(c->"\n\n".charAt(c-65))
             //   Convert the character to its value
   .sum()    //   And sum it all together

```

# Answer
> 5 votes
# , ~~90~~ 63 bytes

```
function(W,u=utf8ToInt)sum(u('

')[u(W)-64])

```

Try it online!

Takes input as an uppercase string. R handles unprintables and multiline strings without issues, so that's nice. Now we're almost twice the external package!

And because CRAN has so many random goodies:

# \+ ScrabbleScore 31 bytes

```
ScrabbleScore::sws(scan(,""),F)

```

Try it online!

Sadly, `sws` checks for validity by default.

# Answer
> 5 votes
# Octave / MATLAB, 85 bytes

```
@(x)sum([1:4 7 9]*any(reshape(char(strsplit('DG BCMP FHVWY K JX QZ')),6,1,5)==x,3)+1)

```

Try it online!

# Answer
> 5 votes
# Jelly, 19 bytes

```
Oị“ÆẠḃbṂƬɠF#ṁ²’ḃ⁵¤S

```

A monadic link accepting a list of upper-case characters which returns an integer

**Try it online!** Or see the test-suite.

### How?

```
Oị“ÆẠḃbṂƬɠF#ṁ²’ḃ⁵¤S - Link: list of characters
O                   - ordinals ('A'->65, B->66...)
                 ¤  - nilad followed by link(s) as a nilad:
  “ÆẠḃbṂƬɠF#ṁ²’     -   literal 14011114485013321424185131
                ⁵   -   literal 10
               ḃ    -   bijective-base = [1,3,10,1,1,1,1,4,4,8,4,10,1,3,3,2,1,4,2,4,1,8,5,1,3,1]
 ị                  - index into (1-based & modular) (vectorises)
                    -  i.e. mapping from: O P  Q R S T U V W X Y  Z A B C D E F G H I J K L M N)
                  S - sum

```

# Answer
> 4 votes
# Haskell, 66 bytes

```
sum.map(\c->1+read["02210313074020029000033739"!!(fromEnum c-65)])

```

Try it online! Same approach as DanielIndie's JavaScript answer.

---

### Haskell, ~~82~~ 81 bytes

```
sum.map(\c->1+sum(read.pure<$>lookup c(zip"DGBCMPFHVWYKJXQZ""1122223333347799")))

```

Try it online!

# Answer
> 4 votes
# Emojicode, 358 bytes

```
➡s 0ls➕sa1e1i1l1n1o1r1s1t1u1d2g2b3c3m3p3f4h4v4w4y4k5j8x8q10z10ls 10

```

Try it online!

## Explanation:

I changed the variable names from single letters to more meaningful words, and expanded some parts of my code to hopefully make it more readable for people unfamiliar with the language. You can test the expanded program here.

```
       define a class that takes a string
 ➡     define a method that returns a string
  values     create int dictionary
   a1 e1 i1 l1 n1 o1 r1 s1 t1 u1 d2 g2
   b3 c3 m3 p3 f4 h4 v4 w4 y4 k5 j8 x8
   q10 z10
           ^ dictionary contains letters(keys) and their numerical values

  score 0                          declare 'score' variable and set to 0
   iterator                      transform input string to iterator
    letter iterator                 iterate over each byte in input string
     score➕score values letter    add value of each letter to score

  score 10     return the score as a string

           begin the program here
 abc     call scoring method and print the score
 ppcg     repeat with other test cases
 stewie
 fizzbuzz
 abcdefghijklmnopqrstuvwxyz

```

# Answer
> 4 votes
# PowerShell, 60 bytes

```
$args|% t*y|%{$s+='02210313074020029000033739'[$_-65]-47}
$s

```

Try it online!

# Answer
> 3 votes
# 05AB1E, 21 bytes

Takes input as a lowercase list of characters.

```
•_JÊ¿ùã$Ƶ½œM•11вAIkèO

```

Try it online! or as a Test suite

# Answer
> 3 votes
# Octave, 73 bytes

```
@(x)sum('09977433333222211'(([~,y]=ismember(x,'QZJXKFHVWYBCMPDG'))+1)-47)

```

Try it online!

Uses `ismember` to map each character in the input stream `x` onto it's index in the lookup string `'QZJXKFHVWYBCMPDG'`. Any element not found will be mapped to an index of 0 (this will include the 1-point characters).

Next we add 1 to the index to make the 0's become valid 1-index references, and lookup into the string `'09977433333222211'`. This is one element longer than the first lookup string. The digits represent the point value of each element in the original string, minus 1, with the extra element being a '0' at the `beginning` .

Finally the resultant string is converted to integers by subtracting `47` (`'0'-1`), yielding the point value for each letter, and all point values are then summed.

# Answer
> 3 votes
# C++, 95 bytes

```
char*m="02210313074020029000033739";
int f(char*p){int n=0;while(*p)n+=m[*p++-65]-47;return n;}

```

Try it online (not a TIO link sorry)

Explanation:

* Declares `m`, an array of the values of each letter in order, minus 1. The minus 1 is because of Q and Z: I couldn't have a two digit number in there
* Iterates through through the string `p` until we get to null character, and adds the score of the number (`*p` gives us the letter, and `-65` so we can properly index the array). Since `m` is a `char*` it converts to a `char` so we minus `48` so bring it back to 0, but add `1` since `m` is declared as one score less for each character.

I'm not an avid poster here so I hope I've done this correctly. I believe they returning `n` counts as printing the value, and that declaring a function is fine.

# Answer
> 3 votes
# K (oK), ~~60~~ 38 bytes

**Solution:**

```
+/1+.:'"02210313074020029000033739"65!

```

Try it online!

**Explanation:**

Index into the scores, sum up result.

```
+/1+.:'"02210313074020029000033739"65! / the solution
                                   65! / input modulo 65 to get position in A-Z
       "02210313074020029000033739"    / index into the scores (1 point lower)
    .:'                                / value (.:) each (') to convert to ints
  1+                                   / increase by 1
+/                                     / sum up

```

# Answer
> 3 votes
# PowerShell, 92 bytes

```
$args|% T*y|%{$i+=switch -r($_){[DG]{2}[BCMP]{3}[FHVWY]{4}K{5}[JX]{8}[QZ]{10}default{1}}};$i

```

Try it online!

Didn't notice @Add-TheNewOne's answer before writing this, but I think it's fairly different in any case.

# Answer
> 3 votes
# 05AB1E, 18 bytes

```
•Q<ß÷λv¸Ïàœ¶•IÇè>O

```

Try it online!

Explanation:

```
•Q<ß÷λv¸Ïàœ¶•           # compressed integer 30740200290000337390221031
             IÇ         # codepoints of the input
               è        # index into the digits of the large integer
                >       # increment each
                 O      # sum

```

The large integer encodes the point value of each letter. Since encoding numbers in the range 1-10 would be inconvenient, we subtract 1 so that each one fits on a single digit (this is why the `>` is needed).

Note that indexing in 05AB1E wraps around, so the first digit of the number actually corresponds to "h" ("h"'s codepoint is 104, which is 0 mod 26). This is convenient: since numbers can't start with 0, we don't want the first digit to correspond to "a".

Alternative 18-byter:

```
A•Θ¡₆öηÖ&'/α°•R‡>O

```

Try it online!

`A` pushes "abcdefghijklmnopqrstuvwxyz".  transliterates, replacing each letter in the input with the corresponding digit in the compressed integer. `A‡` saves one byte over `IÇè`; unfortunately, this encoding puts "a" first, so we have to use `R` (reverse) to get around the issue that numbers can't start with 0.

Yet another 18-byter:

```
žW•Δÿ¦ÝZ=áí4_ø•‡>O

```

Try it online!

Same idea as above, but this one uses the obscure `žW` built-in to push "qwertyuiopasdfghjklzxcvbnm". `žW` is one byte longer than `A`, but it saves the `R` since "q" isn't a 1-point letter.

# Answer
> 3 votes
# Beatnik, 379 bytes

```
K ZZZZKF ZD ZD ZD ZD ZD ZD ZD
K ZZZZZZZZA J Z ZD ZB B
K XA KD ZD ZF F ZA ZD KF KF ZD ZB B
K D Z ZD ZB B
K ZF Z ZD ZF KA ZA ZD ZD KF KF KF ZD ZB B
K A KD ZD ZF D ZA KF ZD ZB B
K ZF KD ZD ZB B
K D Z ZD ZB B
K A Z ZD ZB B
K ZF Z ZD ZB B
K D Z ZD ZF D ZA KF ZD ZB B
K Z KD ZD ZB B
K B Z ZD ZB B
K Z Z ZD ZB B
K A Z ZD ZF F ZA KF ZB Z
K K KD ZD ZB B
K B Z ZF A KF
KF
XX ZZZZZZZZZZZZZX

```

Try it online!

See also MickyT's answer.

# Answer
> 2 votes
# Japt `-x`, ~~43~~ ~~39~~ ~~35~~ 30 bytes

```
£2+`dglbcÛghvwylk¥ljx¥qz`qÊaøX

```

Try it online!

## 35 byte solution:

```
¬£Ò('0+#Ý03#740#È29e4+33739 g65nXc

```

Run it online

# Answer
> 2 votes
# Retina 0.8.2, 41 bytes

```
T`BCDGJKMPQXZF\HVWY`221174229793
.
$*..
.

```

Try it online! Link includes test cases. Explanation: Like the Haskell answer, nontrivial letters are translated to 1 less than their score, and 1 is added later when the characters are converted to unary. Putting `FHVWY` last allows them all to map to a score of 3 + 1.

# Answer
> 2 votes
# Japt, 36 bytes

```
¬£2+`dg
bcmp
fhvwy
k

jx

qz`·bøX
x

```

Takes input as a lowercase string, returns a number.
Short explanation:

```
¬£2+`dg
¬       // Split the input into chars,
 £      // then map over each char, returning
  2+`dg // 2 plus

qz`·bøX
    bøX // the char's index in
qz`·    // the hardcoded string split by newlines.
x       // And finally sum the whole thing.

```

Try it online!

# Answer
> 2 votes
# Ruby, 60 bytes

```
->s{s.sum{|c|"BDDCBECEBIFBDBBDKBBBBEEIEK"[c.ord-65].ord-65}}

```

Try it online!

A lambda, accepting input as an array of (uppercase) characters and returning an integer.

# Answer
> 2 votes
# Perl 5 `-pF`, 50 bytes

```
_1DG2BCMP3FHVWY4K7JX9QZ=~/\d\D*$_/,$\+=1+$&for@F}{

```

Try it online!

# Answer
> 2 votes
# Gforth, 109 Bytes

```
: V s" 1332142418513113:11114484:" ; : C 0 NAME 0 DO DUP C@ 65 - V DROP + C@ 48 - ROT + SWAP 1+ LOOP DROP . ;

```

Input must be uppercase:
`C PPCG 11 OK`

## Readable

```
\ String used as table with values for each letter in the alphabet
\ : follows 9 in the ASCII-table
: V
   s" 1332142418513113:11114484:"
;

: C
   0                   \ Initialize sum        ( sum               )
   NAME                \ Get the string        ( sum  c-addr count )
   0 DO                \ Start of loop         ( sum  c-addr       )
      DUP C@           \ Get letter            ( sum  c-addr char  )
      65 -             \ Calculate table index ( sum  c-addr index )
      V DROP + C@      \ Get table entry       ( sum  c-addr entry )
      48 -             \ Calculate entry value ( sum  c-addr value )
      ROT + SWAP       \ Update sum            ( sum' c-addr       )
      1+               \ Next character        ( sum' c-addr'      )
   LOOP
   DROP .              \ Drop c-addr and print result
;

```

Try it online!

# Answer
> 2 votes
# C (gcc), ~~78~~ 72 bytes

```
i;f(char*s){for(i=0;*s;)i+="\n\n"[*s++-65];s=i;}

```

There are actually 26 characters in that string. See the code rendered properly and run it here.

Thanks to gastropner for golfing 6 bytes.

Ungolfed version:

```
i; // declare a variable to store the score; it is implicitly of type int
f(char* s) { // function taking a string as argument and implicitly returning an int
    for(i = 0; // initialize the score to 0
        *s; ) // iterate over the string until we hit terminating NUL byte
        i += "\n\n"[*s++ - 65]; // this is a 26-char string containing the ASCII equivalent of each numeric scrabble value; 65 is ASCII code for 'A', mapping the alphabet onto the string
    s = i; // implicitly return the score
}

```

# Answer
> 2 votes
# C# (.NET Core), 50 + 18 = 68 bytes

```
s=>s.Sum(c=>"02210313074020029000033739"[c-65]-47)

```

+18 bytes for `using System.Linq;`

Try it online!

# Answer
> 2 votes
# Perl 6, 52 bytes

```
{TR/A..Z/02210313074020029000033739/.comb.sum+.ords}

```

Try it online!

Maps every character to a digit, and sums them. And adds 1 for each character because there isn't a digit 10 without incurring unicode bytes.

# Answer
> 2 votes
# Excel, 91 bytes

```
{=LEN(A1)+SUM(0+("0"&MID("02210313074020029000033739",CODE(MID(A1,ROW(A:A),1)&"z")-64,1)))}

```

Explanation:

* Input is in cell `A1`
* The formula must be entered as an array formula with `Ctrl`+`Shift`+`Enter`, which adds the curly brackets `{ }` to both ends.
* `MID(A1,ROW(A:A),1)` pulls out each character in turn (and a lot of empty values, too, since it's going to return as many values as there are rows in the sheet)
* `CODE(MID(~)&"z")` pulls out the ASCII value for the each character. The `&"z"` appends a `z` to the end of the `MID()` result because `CODE()` doesn't like empty inputs. The ASCII value for `z` is higher than every capital letter, though, so it's effectively ignored later.
* `MID("02210313074020029000033739",CODE(~)-64,1)` pulls out a letter from the score string based on its ASCII value adjusted down by 64 so the letters run 1-26 instead of 65-90.
* `"0"&MID(~)` prepends a zero to the `MID()` result because Excel won't let you do math with empty strings, of which there will be several.
* `0+("0"&MID(~))` turns all those strings into numbers.
* `SUM(0+("0"&MID(~)))` adds up all those strings that are now numbers.
* `LEN(A1)+SUM(~)` adds the length of the input to the sum because all the values in the score string (`02210313074020029000033739`) were adjusted down by one so they would all be one digit long.

---

There's a very similar solution in Google Sheets but it comes in at 97 bytes because `ArrayFromula()` is longer than `{}` (but at least it can handle `0 + "" = 0`).

```
=Len(A1)+ArrayFormula(Sum(0+Mid("02210313074020029000033739",Code(Mid(A1,Row(A:A),1)&"z")-64,1)))

```

# Answer
> 2 votes
# Wolfram Language (Mathematica), 74 bytes

Of course Wolfram|Alpha supports Scrabble scoring! This is an anonymous function.

```
Plus@@(First[WolframAlpha["Scrabble "<>##,"NumberData"]]&/@Characters[#])&

```

This doesn't work on TIO.

To run, go **here**, scroll down and click "Create a New Notebook »". The code to use in the notebook is in this TIO program so you can copy it. Paste each function call in its own code block. If you run too many in a single block, the execution won't complete.

Note that `WolframAlpha` sends a request using the Internet. Though there are other answers on PPCG that use it, I thought you should know.

This program uses the below shorter function, but calls it on *each individual character* of the input (sending a separate call to Wolfram|Alpha each time!)

---

This only works for input up to length 15, the width of a Scrabble board. (49 bytes)

```
First[WolframAlpha["Scrabble "<>#,"NumberData"]]&

```

---

Same as above, but will display the result in a box, along with whether the input is a valid Scrabble word. (45 bytes)

```
First[WolframAlpha["Scrabble "<>#,"Result"]]&

```

# Answer
> 2 votes
# APL (Dyalog Extended), 40 bytes

```
+/1+⍎¨'02210313074020029000033739'[⎕A⍳⎕]

```

The same method as the K answer, index into a list of scores, add 1 to them, and sum.

Try it online!

# Answer
> 2 votes
# Zsh \+ `bc`, 54 bytes

```
bc<<<$#1`tr a-z 02210313074020029000033739<<<${1///+}`

```

Try it online!

# Pure Zsh, 55 bytes

```
<<<$[$#1`tr a-z 02210313074020029000033739<<<${1///+}`]

```

Try it online!

# Answer
> 2 votes
# Python 3, 70 bytes

This isn't any better than Rod's answer (which is also 70 bytes) but it is a different approach than the other answers I see in this thread so I figured I'd submit it anyway.

```
lambda s:sum(0xa48441111a3113158142412331>>4*(ord(c)-97)&15for c in s)

```

Try it online!

# Shorter version, 68 bytes

-2 bytes thanks to xnor, now making this better than the previous Python answer!

```
lambda s:sum(0xa48441111a3113158142412331>>ord(c)%97*4&15for c in s)

```

Try it online!

# Answer
> 1 votes
# JavaScript (ES6), 69 bytes

Takes input as an array of characters.

```
s=>s.map(c=>t-=~'9200204703130122093733'[parseInt(c,36)*25%26],t=0)|t

```

Try it online!

# Answer
> 1 votes
# Bash + GNU utilities, 64

```
sed -es/[{QZ]/JD,JX]/KB,K]/FE,FHVWY]/BE,BCMP]/DE,DG]/EE}/g|wc -c

```

Try it online!

Input read from STDIN. Uses a brace expansion to generate sed expressions equivalent to those in my sed answer.

# Answer
> 1 votes
# Perl 6, 55 bytes

```
{sum .map:{:36<Z3P8JOBRZ4X1FBXLWSVL>+>(.ord*4-260)%16}}

```

Try it online!

Takes an array of characters. Uses a 4-bit lookup table encoded in base-36.

# Answer
> 1 votes
# Perl 5 `-pF`, 73 bytes

```
$\+=(1,3,3,2,1,4,2,4,1,8,5,1,3,1,1,3,10,(1)x4,4,4,8,4,10)[-65+ord]for@F}{

```

Try it online!

# Answer
> 1 votes
# Red, 97 bytes

```
func[s][t: :to-integer n: 0 foreach c s[n: n - 47 + t pick{02210313074020029000033739}t c - 64]n]

```

Takes a string as input.

## Explanation of the ungolfed solution:

```
f: func[s][
    n: 0                  ; n will store the sum
    foreach c s [         ; for each character in the argument
        n: n - 47 + to-integer pick {02210313074020029000033739} to-integer c - 64
                          ; find its offset from "A" (to-integer c - 64)
                          ; use this as an index in the string with scores (pick {...} ...)
                          ; to extract the score and convert it to an integer
                          ; increase it with 1 and add it to the sum
    ]
    n                     ; return the sum
]

```

Try it online!

# Answer
> 1 votes
# Pip, ~~34~~ 33 bytes

```
1+("3V1S1QFRU1SMQ12W7"FB36)@A_MSa

```

Takes input in lowercase as a command-line argument. Try it online!

### Explanation

We map a function to each character of the command-line argument `a` and sum the results using `MS`.

In the function, we convert the argument `_` to its ASCII code using `A`, and then use that to index into the magic number `30740200290000337390221031`. With cyclic indexing, this maps `a` -\> `0`, `b` -\> `2`, ... , `z` -\> `9` (one less than the Scrabble score). We then add `1` to get the correct score of each letter.

We save one byte by encoding the number in base 36 (the highest base Pip's builtin base conversion can handle) as the string `"3V1S1QFRU1SMQ12W7"` and then converting it from base 36 to decimal using `FB`.

# Answer
> 1 votes
# SmileBASIC, ~~87~~ ~~85~~ 78 bytes

```
INPUT S$WHILE""<S$S=S+VAL(@2210313074020029000033739[ASC(POP(S$))-65])+1WEND?S

```

Old method:

```
INPUT S$WHILE""<S$S=S+(INSTR(@DG+@___BCMP_FHVWYK*2+"JX"*4+@QZ,POP(S$))+4)DIV 5+1WEND?S

```

# Answer
> 1 votes
# Go, ~~96~~ 94 bytes

```
func(i string){a,s:=`

`,0;for _,c:=range i{s+=int(a[c-65])};print(s)}

```

Go allows any byte sequence in a raw string, except `\r` and ```, this saves about 3 bytes off the total.

This is just a remix of existing solutions in other languages, so no real new innovation here.

Edit: I missed the memo where we dont have to name our functions

Try it online!

# Answer
> 1 votes
# Powershell with amazing 297 Bytes

Any idea to make the script shorter?

```
$1=read-Host
$s=0
$l=$1.ToCharArray()
$l|%{switch($_){{'E','A','I','O','N','R','T','L','S','U'-contains$_}{$s+=1}{'D','G'-contains$_}{$s+=2}{'B','C','M','P'-contains$_}{$s+=3}{'F','H','V','W','Y'-contains$_}{$s+=4}{'J','X'-contains$_}{$s+=8}{'Q','Z'-contains$_}{$s+=10}{'K'-contains$_}{$s+=5}}}
$s

```

# Answer
> 1 votes
# x86-machine code, IBM PC DOS, 37 bytes

```
00000000: bb18 0133 d2ac 2c41 d0e8 9cd7 d410 9d72  ...3..,A.......r
00000010: 0286 e002 d0e2 eec3 1332 1424 1851 3113  .........2.$.Q1.
00000020: a111 1448 4a                             ...HJ

```

Listing:

```
BB 0118     MOV  BX, OFFSET TBL     ; load score table into BX
33 D2       XOR  DX, DX             ; clear letter count
        LOOP_LETTER:
AC          LODSB                   ; load next char from DS:SI into AL, advance SI
2C 41       SUB  AL, 'A'            ; convert letter to zero-based index
D0 E8       SHR  AL, 1              ; divide index by 2, set CF if odd index
9C          PUSHF                   ; save CF
D7          XLAT                    ; AL = packed score byte
D4 10       AAM  16                 ; unpack nibbles into AH/AL (clobbers CF though)
9D          POPF                    ; restore CF
72 02       JC   ODD                ; if odd index, use low nibble
86 E0       XCHG AH, AL             ; otherwise is even, use high nibble
        ODD:
02 D0       ADD  DL, AL             ; add tile to score
E2 EE       LOOP LOOP_LETTER        ; loop through all letters
C3          RET                     ; return to caller
        TBL:
            DB 013H,032H,014H,024H,018H,051H,031H,013H,0A1H,011H,014H,048H,04AH

```

Try it online!

*Note: using link above, re-run with input on command line like `ASM ABC`, etc.*

As a callable function, input string at `[SI]`, length in `CX`. Output to `DX`.

**Explanation**

Uses a score table of 4-bit nibbles for each tile's score. Loops through the input string and converts each letter to a zero-based index. Each index is divided by two to find the corresponding byte in the table. The low nibble is added if the index is odd, otherwise the high nibble is added if the index is even.

**Test Program I/O**

# Answer
> 1 votes
# brainfuck, ~~386~~ 382 bytes

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

```

Try it online!

Pretty much ungolfed, but first brainfuck code for this question. This code can only handle uppercase letters. Any other symbol will lead to an endless loop. Also the maximum score depends on the used bf-interpreter. On tio.run this can handle scores up to 254.

```
points:
abcde fghij klmno pqrst uvwxyz
13321 42418 51311 3x111 14484x (x = 10)

tape:
[input], 0, [points table], 0, 0, score
input: current letter marker (0 or neg 1), current letter
points table: check letter marker (0 or neg 1), points

code:
-           set current letter marker
>,[>>,]     input characters

->          set check letter marker
            fill points table
+>>+++>>+++>>++>>+>>
++++>>++>>++++>>+>>++++++++>>
+++++>>+>>+++>>+>>+>>
+++>>++++++++++>>+>>+>>+>>
+>>++++>>++++>>++++++++>>++++>>++++++++++

+[-<<+]->                   go to first input letter
+                           bugfix: intersecting pointers
[                       main loop
  -                         bugfix: intersecting pointers
  >++++++++[<-------->-]<-  subtract 65 from current letter (ASCII A)
  [                         check loop: mark the entry in points table that's related to the current letter
    [->+]                   decrease letter and go to check letter marker
    >>-                     set new check letter marker
    <+[-<+]-                go back to current letter marker
    >                       go to current letter
  ]
                            the related points entry is found so we need to add the points to the score
  +[->+]->                  go to related points entry
  [                     addition loop
    ->+                     decrease points entry and save points to temporary cell
    >[>>]>+                 go to score and add 1
    +[-<+]->                go back to related points entry
  ]
  >[-<+>]                   move points back from temp cell
  <<+                       delete "check letter marker"
  <[<<]>-                   set "check letter marker" at A
  <+[-<+]                   go to current letter marker
  >>-                       set new current letter marker
  >                         next input letter
  +                         exit loop if cell pointer is at "check letter marker" position
]

>[>>]>                      go to score
                            number printing routine from esolangs
>+[[-]<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->+<[->[-]>>+>+<<<]]]]]]]]]<]>>[>]++++++[-<++++++++>]>>]<<<[.[-]<<<]

```

if unary output is allowed then this ~~297~~ 293 bytes code can be used:

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

```

Try it online!

# Answer
> 1 votes
# SNOBOL4 (CSNOBOL4), 224 bytes

```
	V =ARRAY(10,0)
	V<1> ='EAIONRTLSU'
	V<2> ='DG'
	V<3> ='BCMP'
	V<5> ='FHVWY'
	V<8> ='JX'
	V<10> ='QZ'
	I =INPUT
N	S =I
	X =LT(X,10) X + 1	:F(O)
R	S ANY(V<X>) =	:S(R)
	O =O + X * (SIZE(I) - SIZE(S))
	I =S	:(N)
O	OUTPUT =O
END

```

Try it online!

*Very* naive approach. Stores the letters in an `ARRAY` with indices equal to the scores. It tries to match `0` for point values that don't exist, which ends in a score of 0.

```
	V =ARRAY(10,0)			;* set up value array of 10 values with contents all 0
	V<1> ='EAIONRTLSU'		;* set contents at appropriate indices
	V<2> ='DG'
	V<3> ='BCMP'
	V<5> ='FHVWY'
	V<8> ='JX'
	V<10> ='QZ'
	I =INPUT			;* read input
N	S =I				;* begin Next iteration
	X =LT(X,10)	X + 1	:F(O)	;* increment X or GOTO output
R	S ANY(V<X>) =	:S(R)		;* replace ANY letters in V<X> with nothing
	O =O + X * (SIZE(I) - SIZE(S))	;* add to the score
	I =S	:(N)			;* set I to S and goto N
O	OUTPUT =O
END

```

# Answer
> 1 votes
# Rockstar, ~~187~~ ~~184~~ ~~156~~ 154 bytes

```
listen to W
cut W in S
cut W
while W
roll W in X
P's 1
cut "DG1BCMP1FHVWY1K111JX11QZ" in T
while T
roll T in L
let P be+L's 1
let S be+L's X and P

say S

```

Try it here (Code will need to be pasted in)

Abuses a nice little feature in Rockstar whereby the variable (`S` in this case) an array is assigned to can be used to reference both the array (e.g., `S at index`) or, by itself, the length of the array. So, by `cut`ting the input `W`ord into the array `S` we, straight away, have a base score of 1 point per letter.

```
listen to W        :Read input into variable W
cut W in S         :Split W into variable S (our score)
cut W              :Split W
while W            :While W is not empty
roll W in X        :  Pop first element of W into variable X
P's 1              :  Initialise P as 1 (base score for each tile)
cut "..." in T     :  Split "DG1BCMP1FHVWY1K111JX11QZ" into variable T
while T            :  While T is not empty
roll T in L        :    Pop first element of T into variable L
let P be+          :    Increment P by
  L's 1            :      Is L equal to 1?
let S be           :    Increment S by
  L's X            :      Is L equal to X?
  and P            :      Logical AND with P
                   :  End while loop
                   :End while loop
say S              :Output S

```

# Answer
> 1 votes
# Thunno 2 `S`, 20 bytes

```
Ä⁻»yŒṄȦẏÄb¶Ỵɓæ»11Bsi

```

Attempt This Online!

#### Explanation

```
Ä⁻»yŒṄȦẏÄb¶Ỵɓæ»11Bsi  # Implicit input
Ä⁻                    # Convert input to 0-based indices in alphabet
  »yŒṄȦẏÄb¶Ỵɓæ»       # Compressed integer 140755590392038037755694497
               11B    # Converted to base 11 as a list:
                      # [1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10]
                      # (A, B, C, D, E, ...)
                  si  # Index into the list
                      # Implicit output of the sum

```

# Answer
> 1 votes
# Vyxal `rs`, 20 bytes

```
øA11»⟑↑Gp→₃ꜝ¬∑"Ż¶»τİ

```

Try it Online!

port of thunno 2 answer but I needed an extra byte for the compressed number since vyxal cant zero index letters to numbers

# Answer
> 0 votes
## Visual Basic for Applications, 117 bytes

```
s=inputbox(u):for i=1to 16:s=replace(s,mid("DGBCMPFHVWYKJXQZ",i,1),space(mid("1122223333347799",i,1)+1)):next:?len(s)

```

Run in immediate (debug) window.

# Answer
> 0 votes
# PHP, 74 bytes

```
while($c=$argn[$i++])$s+=1+_02210313074020029000033739[ord($c)&31];echo$s;

```

case insensitive. Run as pipe with `-nR` or try it online.

# Answer
> 0 votes
# C# (.NET Core), 48 + 18 = 66 bytes

```
s=>s.Sum(c=>"!#C²!$1$$XhQJ"[c%13]-16>>c%2*4&15)

```

+18 bytes is for `using System.Linq;`

Try it online!

# Answer
> 0 votes
# T-SQL, 106 bytes

Accepting uppercase characters.

Inserted a line break to make this readable:

```
DECLARE @ varchar(max)='ABCDEFGHIJKLMNOPQRSTUVWXYZ'

WHILE'='<@
SET
@=stuff(@,1,1,'')+'-~'+substring('02210313074020029000033739',ascii(@)-64,1)
EXEC('print'+@)

```

# Answer
> 0 votes
# Julia 1.0, 49 bytes

```
!x=sum(i->b"\1\3\3\2\1\4\2\4\1\b\5\1\3\1\1\3\n\1\1\1\1\4\4\b\4\n"[i-'@'],x)

```

(the special characters are escaped here for clarity)

Try it online!

---
Tags: code-golf, string, number, game, board-game
---


title: Find the pattern

text:
# Question
Title: Find the pattern
I feel tired to do "find the pattern" exercise such as

```
1 2 3 4 (5)
1 2 4 8 (16)
1 2 3 5 8 (13)

```

Please write a program that finds the pattern for me.

Here, we define the pattern as a recurrence relation that fits the given input, with the smallest score. If there are multiple answers with the same smallest score, using any one is fine.

Let the \\$k\\$ first terms be initial terms (for the recurrence relation, etc.), and the \\$i\\$'th term be \\$f(i)\\$ (\\$i\>k,i\in\mathbb N\\$).

* A non-negative integer \\$x\\$ adds\\$\lfloor\log\_2\max(|x|,1)\rfloor+1\\$ to the score
* The current index \\$i\\$ adds \\$1\\$ to the score
* `+`, `-`, `*`, `/` (round down or towards zero, as you decide) and `mod` (`a mod b` always equal to `a-b*(a/b)`) each add \\$1\\$ to the score
* For each initial term \\$x\\$, add \\$\lfloor\log\_2\max(|x|,1)\rfloor+2\\$ to the score
* \\$f(i-n)\\$ (with \\$n\le k\\$) adds \\$n\\$ to the score. E.g. Using the latest value \\$f(i-1)\\$ add \\$1\\$ to the score, and there must be at least 1 initial term.
* Changing the calculation order doesn't add anything to the score. It's fine if you write `1+i` as `1 i +`, `+(i,1)` or any format you like.

Samples:

```
input   -> [score]    expression
1 2 3 4     -> [1]    f(i) = i
1 2 4 8     -> [5]    f(1) = 1, f(i) = f(i-1)+f(i-1)
1 2 3 5 8   -> [9]    f(1) = 1, f(2) = 2, f(i) = f(i-1)+f(i-2)

```

Shortest program in each language wins. It's fine if your program only solve the problem theoretically.

# Answer
> 4 votes
# Python, 554 bytes

```
lambda s:next((s[:i],x)for n in N()for i in R(A(s))if(b:=sum(map(lambda k:A(bin(abs(k)))-1,s[:i])))<n for x in X(n-b,i)if all(E(s,x,j)==s[j]for j in R(i,A(s))))
E=lambda s,x,i:x if int==type(x)else i+1if"i"==x else s[i-x[1]]if"@"==x[0]else.5if(r:=E(s,x[2],i))==0else[(l:=E(s,x[1],i))+r,l-r,l*r,l//r,l%r]["+-*/%".index(x[0])]
A=len
R=range
def X(k,i):
 for x in["i",0]*(k==1)+[["@",k]]*(k<=i)+[[op,l,r]for a in R(1,k-1)for r in X(k-a-1,i)for l in X(a,i)for op in"+-*/%"if k>2]:yield x
 for n in R(2**(k-1),2**k):yield n
def N(k=0):
 while 1>0:k+=1;yield k

```

Attempt This Online!

*running the test-cases takes approximately 30 seconds*

*The running time is at exponential in the score, so the program may take extremely long to finish if the sequence has a score of more than 10*

Output format:

1. array of initial values
2. expression for remaining values

* `i`: index, integers -\> constants
* `["@",k]` -\> `f(i-k)` (for k any integer)
* `[op,l,r]` -\> `l op r` (l,r expressions; op operation)

Uses `%` for mod (I can change it if it is a problem)

for example: `([1, 1], ['+', ['@', 1], ['@', 2]])` -\> `f(1)=f(2)=1, f(i)=f(i-1)+f(i-2)`

## Explanation

Go through all expressions in order of score

`expressions(k,i)` (golfed: `X`) generates all expressions with score `k` and `i` initial elements

`check` and `evaluate` (golfed: in-lined/`E`) evaluate the expression to check if it generates the sequence

The main function goes through all expressions ordered by score and returns the first expression that computes the sequence.

ungolfed version:

```
def evaluate(seq,expr,i):
 if type(expr)==int:
  return expr
 if expr=="i":
  return i+1
 if expr[0]=="@":
  return seq[i-expr[1]]
 if expr[0]=="+":
  return evaluate(seq,expr[1],i)+evaluate(seq,expr[2],i)
 if expr[0]=="-":
  return evaluate(seq,expr[1],i)-evaluate(seq,expr[2],i)
 if expr[0]=="*":
  return evaluate(seq,expr[1],i)*evaluate(seq,expr[2],i)
 if expr[0]=="/":
  return evaluate(seq,expr[1],i)//evaluate(seq,expr[2],i)
 if expr[0]=="%":
  return evaluate(seq,expr[1],i)%evaluate(seq,expr[2],i)

def check(seq,n_initTerms,expr): ## check if expr is an expression for this sequence
 try:
  for i in range(n_initTerms,len(seq)):
   if not evaluate(seq,expr,i)==seq[i]:
    return False
  return True
 except:
  return False

def expressions(k,i):
 if k==1:
  yield "i"
 if k<=i:
  yield ["@",k]
 if k>2:
  for a in range(1,k-1):
   for op in "+-*/%":
    for l in expressions(a,i):
     for r in expressions(k-a-1,i):
      yield [op,l,r]
 for n in range(2**(k-1),2**k):
  yield n
 if k==1:
  yield 0

def find(seq):
 n=1;
 while True:
  for i in range(len(seq)-1):
   base_score=sum(map(lambda k:len(bin(abs(k)))-2,seq[:i]))
   if base_score<n:
    for expr in expressions(n-base_score,i):
     if check(seq,i,expr):
      return (seq[:i],expr)
  n+=1

```

---

# Python, 613 bytes

```
lambda s:min((sum(map(L,s[:i]))+S(s,x),k,s[:i],x)for k in range(2**sum(map(L,s)))if all(E(s,x:=B(k//A(s),i:=k%A(s)),j)==s[j]for j in range(k%A(s),A(s))))[2:]
I=int
A=len
L=lambda k:A(bin(abs(k)))-1
S=lambda s,x:L(x)-1if I==type(x)else 1if"i"==x else x[1]if"@"==x[0]else S(s,x[1])+S(s,x[2])+1
E=lambda s,x,i:x if I==type(x)else i+1if"i"==x else s[i-x[1]]if"@"==x[0]else.5if(r:=E(s,x[2],i))==0else[(l:=E(s,x[1],i))+r,l-r,l*r,l//r,l%r]["+-*/%".index(x[0])]
B=lambda k,i:[q:=(k-i)//3,"i"if k==0else["@",k]if k<=i else[q,-q][r]if(r:=(k-1)%3)<2else["+-*/%"[q%5],B(I((r:=bin(q//5))[2::2],2),i),B(I("0"+r[3::2],2),i)]][1]

```

Attempt This Online!

ungolfed version

# Answer
> 1 votes
# Python3, 1488 bytes:

A rather long approach, but designed to be fast, especially on more common recursive sequences. Explanation of notation coming soon.

```
from math import*
E=enumerate
def V(s,e):
 e,W=e
 if[0,0]==e[:2]:return all(i==e[-1]for i in s)
 if[0]==e[:1]:return all(a==e[1]*i+e[2]for i,a in E(s,1))
 return all(sum(N*s[i-(W-I)-1]for N,(I,_)in e[0])+i*e[1]+e[2]==a for i,a in E(s,1)if i>max(W-j for _,(j,_)in e[0]))
def C(s,c=[]):
 if[]==s and c:yield c;return
 if s:yield from[*C(s[1:],c+[s[0]]),*C(s[1:],c)]
I=lambda V,i:{(0,V),(V//i,V%i)}
def W(x,y):
 t=[[x,1,0],[y,0,1]]
 while t[-1][0]:q=t[-2][0]//t[-1][0];r=t[-2][0]%t[-1][0];t+=[[r,t[-2][1]-q*t[-1][1],t[-2][2]-q*t[-1][2]]]
 return t[-2]
def D(a,b,x,y,g):
 q=[(0,1,x,y),(0,-1,x,y)]
 while q:
  m,d,X,Y=q.pop(0);m+=d
  if all([X,Y]):yield(X,Y)
  J,K=x+m*(b/g),y-m*(a/g)
  if abs(X)+abs(Y)>abs(J)+abs(K)or 0==all([X,Y]):q+=[(m,d,J,K)]
def f(s):
 for O in range(1,len(s)):
  for J in sorted(C([*E(s)][:O][::-1]),key=len):
   if len(J)==1:
    yield([0,s[O]//(O+1),s[O]%(O+1)],O)
    for u in I(s[O]%J[0][1],O+1):
     j=s[O]//J[0][1]
     yield([[(1,J[0])for _ in range(j)],*u],O);yield([[(j,J[0])],*u],O)
   else:
    q=[(J[0][1],[(1,J[0])],J[1:],s[O])]
    while q:
     x,R,S,v=q.pop(0)
     if[]==S:
      for u in I(v,O+1):yield([R,*u],O)
      continue
     y=S[0][1]
     for i in range(v-1):
      if 0==(v-i)%gcd(x,y):
       g,a,b=W(X:=max(x,y),Y:=min(x,y))
       G=(v-i)//g;A,B=[b,a][x>y]*G,[a,b][x>y]*G;
       A,B=min(D(X,Y,A,B,g),key=lambda x:sum(map(abs,x)))
       q+=[(v-i,[(A*z,l)for z,l in R]+[(B,S[0])],S[1:],i)]
def F(s):
 for i in f(s):
  if V(s,i):return i

```

Try it online!

---
Tags: code-golf, math
---