# Question
Title: Convert degrees to one of the 32 points of the compass
The 32-point compass is... interesting, to say the least.

By Denelson83 (Own work) \[GFDL or CC-BY-SA-3.0\], via Wikimedia Commons

Your challenge is to take a degree measure, and convert it into a direction on the 32-point compass.

Each direction is 11.25 (360 / 32) degrees farther than the previous. For example, N (north) is 0 degrees, NbE (north by east) is 11.25 degrees, NNE (north-northeast) is 22.5 degrees, etc.

As for how you're supposed to get the directions,

* 0 degrees is N, 90 degrees is E, 180 degrees is S, and 270 degrees is W.

+ These are called cardinal directions.
* The halfway points between the cardinal directions are simply the cardinal directions they're between concatenated. N or S always go first, and W or E always are second.

+ These are called ordinal directions.
* The halfway points between the cardinal and ordinal directions are the directions they're between concatenated, again, with a "-" in between. Cardinal directions go first, ordinal second.

+ These are called secondary-intercardinal directions.
* The halfway points between secondary-intercardinal directions and other directions are the other directions "by" the cardinal direction they're closest to (other than the one directly next to them, of course).

+ I have no idea what these are called :P

If all this explanation hurts your brain as much as mine, you can refer to this chart:

```
1   North               N
2   North by east       NbE
3   North-northeast     NNE
4   Northeast by north  NEbN
5   Northeast           NE
6   Northeast by east   NEbE
7   East-northeast      ENE
8   East by north       EbN
9   East                E
10  East by south       EbS
11  East-southeast      ESE
12  Southeast by east   SEbE
13  Southeast           SE
14  Southeast by south  SEbS
15  South-southeast     SSE
16  South by east       SbE
17  South               S
18  South by west       SbW
19  South-southwest     SSW
20  Southwest by south  SWbS
21  Southwest           SW
22  Southwest by west   SWbW
23  West-southwest      WSW
24  West by south       WbS
25  West                W
26  West by north       WbN
27  West-northwest      WNW
28  Northwest by west   NWbW
29  Northwest           NW
30  Northwest by north  NWbN
31  North-northwest     NNW
32  North by west       NbW

```

Here is a more detailed chart and possibly better explanation of the points of the compass.

Your challenge is to take input in degrees, and output the full name of the compass direction it corresponds to, along with its abbreviation.

Test cases:

```
Input  Output
0      North N
23.97  North-northeast NNE
33.7   Northeast by north NEbN
73.12  East-northeast ENE
73.13  East by north EbN
219    Southwest by south SWbS
275    West W
276    West by north WbN
287    West-northwest WNW

```

All capitalization must be preserved, as in the test cases. Maximum number of decimal places is 2. All input numbers will be greater than or equal to 0, and less than 360. If a decimal point is present, there will be digits on both sides (you don't have to handle `.1` or `1.`).

This is , so the shortest code in bytes wins.

# Answer
> 4 votes
## Perl, ~~250 236 231 188~~ 187

**Edit:** Some bytes off exploiting symmetry (as I've seen in @bazzargh solution)

**+Edit:** And some evil tricks...

**+Edit**: Back to where I started (working with list, not string), and exploiting more symmetry = 1 byte off and a whole lot uglier.

```
$_=((@_=(1,@_=qw(1b3 1-13 13b1 13 13b3 3-13 3b1),3,map{y/1/2/r}reverse@_)),map{y/312/421/r}@_)[int<>/11.25+.5];print ucfirst s/\w/(' by ',north,south,east,west)[$&]/ger,' ',y/1-4-/NSEW/dr

```

Pretty-printed:

```
$_=(
    (@_=
        (
            1,
            @_=qw(1b3 1-13 13b1 13 13b3 3-13 3b1),
            3,
            map{y/1/2/r}reverse@_
        )
    ),map{y/312/421/r}@_
)[int<>/11.25+.5];

print ucfirst s/\w/(' by ',north,south,east,west)[$&]/ger,' ',y/1-4-/NSEW/dr

```

5.014 required because of `r` modifier.

# Answer
> 7 votes
## Javascript ~~470~~ ~~453~~ ~~438~~ ~~434~~ ~~432~~ ~~421~~ 404

```
s=String;s.prototype.a=s.prototype.replace;var a=prompt()/11.25,a=a+0.5|0,b,k,c=a,d=c%8,c=c/8|0,e=["north","east","south","west"],f,g,h;f=e[c];g=e[(c+1)%4];h=f==e[0]|f==e[2]?f+g:g+f;b="1;1 by 2;1-C;C by 1;C;C by 2;2-C;2 by 1".split(";")[d].a(1,f).a(2,g).a("C",h);k=b.a(/north/g,"N").a(/east/g,"E").a(/south/g,"S").a(/west/g,"W").a(/by/g,"b").a(/[\s-]/g,"");b=b[0].toUpperCase()+b.slice(1);alert(b+" "+k)

```

You can copy this code to your console and execute it. It prompts you for the degrees input and outputs the result with `alert();`

Ungolfed Javascript can be found at this fiddle: http://jsfiddle.net/AezL3/11

# Answer
> 4 votes
# Haskell ~~415~~ ~~372~~ ~~347~~ ~~330~~ ~~317~~ ~~304~~ 301C

Ended up converging on a solution like @VadimR's (and the symmetry's back!). Usage: `h 219` outputs `"Southwest by south SWbS"`

```
d"N"="north"
d"S"="south"
d"E"="east"
d"W"="west"
d"b"=" by "
d"-"="-"
d(x:y)=d[x]++d y
e(x:y)=x:tail(d$x:y)
k 'N'='S'
k 'S'='N'
k 'E'='W'
k x=x
r="N NbE N-NE NEbN NE NEbE E-NE EbN E EbS E-SE SEbE SE SEbS S-SE SbE "
p=words$r++(map k r)
g x=p!!mod(round$x/11.25)32
h x=e(g x)++(filter(/='-')$' ':g x)

```

3 more chars gone, thanks @shiona.

# Answer
> 0 votes
# Python 3.8, ~~482~~ ~~438~~ 424 bytes

```
lambda h:' '.join([b(h),a(a(a(b(h)),1),d={' by ':'b','-':''})])
L=str.lower
c={'North':'N','East':'E','South':'S','West':'W'}
a=lambda t,l=0,d=c:[*(t:=t.replace([i,L(i)][l],d[i])for i in[*d])][-1]
b=lambda h,k=[*c]:a('W|W by x|W-z|Z by w|Z|Z by x|X-z|X by w'.split('|')[int((q:=h*4/45+.5)%8)],d={'W':(W:=[*k][(v:=int(q//8)%4)]),'X':(X:=[*k][(v+1)%4]),'w':(w:=L(W)),'x':(x:=L(X)),'Z':(Z:=[W+x,X+w][W in'EastWest']),'z':L(Z)})

```

Try it online!

This is what I got after some golfing of tony goodwin's answer; posted at its own answer due to the TIO link being too long for a comment. If he chooses to update his answer to the above, I will delete this answer.

I am assuming that it's acceptable to submit a function as a solution rather than a full program. If not, here is a full program at 426 bytes.

I expect that much can still be done to shorten `b`.

**Edit:** Golfed off 44 bytes, courtesy of the majestic walrus. Still don't feel like `b` is done being golfed.

**Edit2:** Shaved off another 14 by unpacking dicts instead of using `keys()` and `items()`.

# Answer
> -1 votes
# Python, ~~2103~~ ~~1647~~ ~~1103~~ ~~1034~~ ~~924~~ ~~889~~ 848 bytes

Very late, I know. Thanks for the challenge, I am setting up a magnetometer for wind direction with my Pi, and wanted a 16 point of compass solution like this to feed into weather forecasting algorithms. All my code is in Python, so here is version of the javascript solution already posted in Python, but with an extra twist that you can specify either 32, 16, or 8 points of the compass at variable j, and I have changed the offset of degHead in the statement before it, depending on the number of points. I used a modified rename alogorithm (and used variables I could rename without corrupting the words!) to ensure I met the case requirements of the question.

I know this won't win, as Python is more wordy, and so am I.

Short version:

```
  def a(t,d,l):
    for i,j in d.items():
      if l:
        i=i.lower()
      t=t.replace(i,j)
    return t
  def b(h,q):
    p=32
    r=360
    h=(h+(r/q/2))/(r/p)
    j=int(int(int(h %8)%8/(p/q))*p/q)
    h=int(h/8)%4
    k=c.keys()
    u=['W','W by x','W-z','Z by w','Z','Z by x','X-z','X by w']
    d={}
    d['W']=list(k)[h]
    d['w']=d['W'].lower()
    d['X']=list(k)[(h+1)%4]
    d['x']=d['X'].lower()
    if(d['W']=='North' or d['W']=='South'):
      d['Z']=d['W']+d['x']
    else:
      d['Z']=d['X']+d['w']
    d['z']=d['Z'].lower()
    return a(u[j],d,0)
  def g(n):
    n=a(n,c,0)
    n=a(n,c,1)
    d={'by':'b',' ':'','-':''}
    return a(n,d,0)
  def v(m):
    while True:
      try:
        return float(input(m))
      except ValueError:
        print("?")
  c={'North':'N','East':'E','South':'S','West':'W'}
  while True:
    h=v("?")
    n=b(h,32)
    print(h,n,g(n))

```

Clear version

```
            import math
            import sys

            def calcPoint(degHead, points):
                maxPoints=32
                if points not in(8,16,32):
                    sys.exit("not a good question")
                degHead=(degHead+(360/points/2))/(360/maxPoints)
                j =int(int( int(degHead  % 8)%8/(maxPoints/points))*maxPoints/points)
                degHead = int(degHead / 8) % 4
                cardinal = ['North', 'East', 'South', 'West']
                pointDesc = ['W', 'W by x', 'W-z', 'Z by w', 'Z', 'Z by x', 'X-z', 'X by w']#vars not compass points
                W = cardinal[degHead]
                X = cardinal[(degHead + 1) % 4]
                w=W.lower()
                x=X.lower()
                if (W == cardinal[0] or W == cardinal[2]) :
                    Z =W + x
                else:
                    Z =X + w
                z=Z.lower()
                return pointDesc[j].replace('W', W).replace('X', X).replace('w', w).replace('x', x).replace('Z', Z).replace('z', z);

            def getShortName(name):
                return name.replace('North', 'N').replace('East', 'E').replace('South', 'S').replace('West', 'W').replace('north', 'N').replace('east', 'E').replace('south', 'S').replace('west', 'W').replace('by', 'b').replace(' ', '').replace('-', '')

            def input_number(msg, err_msg=None):
                while True:
                    try:
                        return float(input(msg))
                    except ValueError:
                        sys.exit("not a number")

            while True:
                headingCalib=input_number("input a number: ")
                print (headingCalib, end=' ')
                name = calcPoint(headingCalib,32) #degrees heading, points of compass 8,16 or 32)
                print (name, end=' ')
                shortName = getShortName(name)
                print (shortName)

```

---
Tags: code-golf
---


title: Find all possible dates

text:
# Question
Title: Find all possible dates
You get a string which contains an integer between `1000` and `99999999` as input. The input string might contain leading zeroes but cannot be longer than 8 characters.

Your goal is to output **all dates between** `6th of December 1919` and `5th of December 2019` which fit the input in these formats:

* day - month - year (dmy)
* month - day -year (mdy)
* year - month - day (ymd)

Days and months can be either one or two digits. Years can be either two or four digits. **Also don't forget the leap years!**

---

Your output dates must be all in the same format (choose one). Its days, months and years must be clearly distinguishable (choose a separator or encode them like YYYYMMDD).

You are free to leave any duplicate dates in your output (you're a good boy if you remove them though). If there are no dates to return, return nothing.

Examples:

```
Input:  "1234"
Output: 1934-02-01, 2012-03-04, 1934-01-02

Input:  "01234"
Output: 1934-01-02, 1934-02-01

Input:  "01211"
Output: 2001-11-01, 2011-01-01, 2001-01-11

Input:  "30288"
Output: 1988-02-03, 1988-02-30, 1988-03-02

Input:  "999999"
Output:

```

Shortest code in bytes wins. Have fun!

# Answer
> 1 votes
# Ruby, 234 bytes

```
require'date'
a,b,g=%w(%Y%-m%d %Y%m%d %Y%-m%-d %Y%m%-d %-m%d%Y %m%d%Y %-m%-d%Y %m%-d%Y %d%-m%Y %d%m%Y %-d%-m%Y %-d%m%Y),Date.new(1920)-26,gets
(b..b+36524).map{|d|puts d.to_s if(a+a.map{|x|x.tr(?Y,?y)}).map{|x|d.strftime(x)}.member?g}

```

Try it online!

I'm willing to bet that this can be shortened this significantly (with regex maybe), but I'm not clever or knowledgable enough to figure that out.

If we are allowed to print the date object itself instead of a string, change `puts d.to_s` to `p d`.

---
Tags: code-golf, date, encoding
---


# Question
Title: Counting Quipu: Base 10 in the New World
Quipus are an ancient device used by the Inca in the Precolumbian era to record numbers in a base ten positional system of knots on a cord, which works as follows:

> Each cluster of knots is a digit, and there are three main types of knots: simple overhand knots; "long knots", consisting of an overhand knot with one or more additional turns; and figure-eight knots.
>
> * Powers of ten are shown by position along the string, and this position is aligned between successive strands.
> * Digits in positions for 10 and higher powers are represented by clusters of simple knots (e.g., 40 is four simple knots in a row in the "tens" position).
> * Digits in the "ones" position are represented by long knots (e.g., 4 is a knot with four turns). Because of the way the knots are tied, the digit 1 cannot be shown this way and is represented in this position by a figure-of-eight knot.
> * Zero is represented by the absence of a knot in the appropriate position.

## Details

For this challenge, each strand of a quipu represents a **single number** (though, as the Wikipedia article states, you *can* represent many numbers on one strand, in this challenge, we shall not).

**Knots**

Each knot will be represented by a single ASCII character.

* `.` represents a simple knot
* `:` represents a one turn of a long knot
* `8` represents a figure-eight knot
* `|` represents the absence of a knot as well as a delimiter between the digits.

**Constructing Quipus**

Quipu are constructed following these rules.

1. Strands run top to bottom in descending order of position (as in, the units digit will be at the bottom end of a strand). Digits along a strand are separated by the character (`|`).
2. The power of 10 a digit represents is determined by its position along the strand in the same way a digit's power of 10 would be calculated using its index in a number with our number system. That is, `24` with a `2` in the tens place and a `4` in the units place, will be represented by two knots, a delimiter (`|`), then four knots.
3. Digits in the same position are aligned towards the bottom of the strand. If one digit in a position will have less knots than other digits of other numbers in the same position, the absence of those knots is represented by (`|`).
4. Consecutive simple knots (`.`) represent a value in their position.
5. Every digit is represented by at least 1 character. When a digits value is 0 for all numbers in a quipu, it is represented by the absence of a knot (`|`).
6. The units place is treated specially. A one in the units place is represented by a figure-eight knot (`8`). A value of two or more in the units place is represented by consecutive long knots (`:`).
7. When the units digit is 0 for all numbers in a quipu the absence of a knot is not printed but, the trailing delimiter for the tens digit is preserved.
8. There is no delimiter following the units digit.

## Rules

* Input will consist of a non-empty list of non-negative integers that may be received through any of the default input methods. You may assume that these integers are all less than or equal to `2147483647` or `2^31-1`. While the test cases are space-delimited, your input format can separate inputs in any way that is convenient for your language, whether that be comma-separated, newline-separated, in an array, and so on.
* Output consists of a single Quipu constructed according to the rules described above. Output may be given through any of the default output methods.
* Your code should be a program or a function, though it does not need to be a named function.
* Knots take some time to tie so to save time, your code as short as possible.

As always, if the problem is unclear, please let me know. Good luck and good golfing!

## Examples

Input:

```
5 3 1 0

```

Output:

```
:|||
:|||
::||
::||
::8|

```

Input:

```
50 30 10 0

```

Output:

```
.|||
.|||
..||
..||
...|
||||

```

Input:

```
330

```

Output:

```
.
.
.
|
.
.
.
|

```

Input:

```
204 1

```

Output:

```
.|
.|
||
||
||
:|
:|
:|
:8

```

Input:

```
201 0 100 222

```

Output:

```
.||.
.|..
||||
|||.
|||.
||||
|||:
8||:

```

Input:

```
1073741823 2147483647

```

Output:

```
|.
..
||
|.
||
.|
.|
.|
..
..
..
..
||
|.
|.
|.
|.
..
..
..
||
.|
.|
.|
..
..
..
..
||
|.
|.
|.
|.
..
..
..
..
||
|.
|.
..
||
.|
.|
..
..
..
..
..
..
||
|.
|.
..
..
||
|:
|:
|:
|:
::
::
::

```

Input:

```
0

```

Output:

```
|

```

Longer test cases

# Further Reading

# Answer
# Pyth, 64 bytes

```
=QjRTQjCmj\|+:R"[8:]"\.PdedCmm+*\|-h.MZdk*?tk\:\8kdC.[L0h.MZlMQQ

```

Try it online!

## How it works

```
=QjRTQ   Converts each number in input to decimal (as a list)
         123 becomes [1,2,3]

----

jCmj\|+:R"[8:]"\.PdedCmm+*\|-h.MZdk*?tk\:\8kdC.[L0h.MZlMQQ

                                              .[L0       Q  0-leftpad each #
                                                  h.MZlMQ   (max length) times

                                             C              transpose

                      mm                    d    for each digit:
                        +                        [convert to] sum of
                         *\|                     "|" repeated
                            -                    the difference of
                             h.MZd               maximum digit in same row
                                  k              and itself.. that many times
                                   *?tk\:\8      and (digit > 1 then ":" or "8") repeated
                                           k     itself many times

the list:
[11,23,52]
->[[1,1],[2,3],[5,2]]
->[[1,2,5],[1,3,2]]
->[["||||8","|||::",":::::"],["||8",":::","|::"]]

                     C      transpose

->[["||||8","||8"],["|||::",":::"],[":::::","|::"]]

  m                          for each number
      +                      [convert to] sum of
                 Pd          every element but the last
       :R"[8:]"\.            with "8" and ":" replaced by "."
                   ed        and the last element
   j\|                       joined with "|"

  C                          transpose
 j                           join (with newlines)

```
> 3 votes

# Answer
# Unreadable, ~~3183~~ 3001 bytes

This was a fun challenge to work on, on and off, in between Christmas celebrations. Thank you for posting! Golfing this was interesting because the specification is full of exceptions and special cases, which required lots of if conditions. Also, while I didn’t need to convert to and from decimal this time, I *did* need a “max” function of sorts to determine the largest number of digits in each number and the largest value of the digits in each place.

**The first version of this was 4844 bytes,** just to give you an idea of how much I golfed this.

The program expects the input as a *comma-separated* list of integers. No spaces or newlines. Using those will produce undefined behavior.

> '""""""'""'""'""'""'""'"""'""""""'"""'""'""'""'""'""'""'""'""'""'""'""""""'""'""'""'""'""'""'"""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""'""""""'""""""""'"""'""'""'""'""'""'""""""'""'"""'""'""'""'""'""'""'""'""'"""'"""""'""""""'"""'""""""""'"""""""'"""'""""""'""""""""'"""'""'""'"""""""'""""""""'"""'"""""'""'""""""'""'""'""'"""'""""""""""'""""'""""""'""'""'"""'"""""""'""'""'""'""'""'""'"""'"""""""""'""""""'""""""'""'"""'""'"""""""'""'"""'""'"""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'""""""'""'""'""'"""'""""""""'"""""""'""'""'""'"""'""""""'""""""'"""'""""""""'"""""""'"""'"""'""""""'"""'""""""""'"""'""""""'""'""'"""'"""""'"""""""'"""""""'"""'""""""'"""'""""""""'"""""""'"""'"""""'""""""'"""'""'"""""""'"""'""""'""""""'""'""'""'"""'""""""""'"""'"""""'""""""""'""""""'"""""""'"""'""'"""""""'"""""""'"""'"""""""""'"""""""""'"""""""'"""""""'"""'"""'"""""""""'""'"""""""'"""'"""'""""""""'"""'""""'""""'""""""'""'"""'""'""'""'""'""'""'""'""'"""'"""""'"""""""'""""""'""'"""'""'"""""""'""'"""'""""'""""'"""""'""""""'""'""'""'""'""'""'""'"""'""""""'""'""'""'""'"""'"""""""'""""""'""'"""'""'"""""""'""'"""'"""'"""""'"""""""'""""""'""'"""'""""""""'"""""""'""'"""'"""""""""'""""""""'"""""""'""""""'""'""'""'""'""'""'""'"""'""""""""'"""""""'""'""'""'""'""'""'""'"""'"""""""""'""""""""'""""""""'"""""""'"""""""'"""'"""""""""'"""""""'""'""'""'"""'""""""'""'""'""'""'"""'"'"""""""""'""'"""""""'"""""""'""'"""'"""""""""'""'""'"""""""'"""""""'""'"""'""""'""""""'"""""""'""'"""'"""""""""'"""""""""'""'"""""""'"""'"""'"""""""""'""'""'"""""""'"""""""'"""'"""'"""""""""'""'""'""'"""""""'"""""""'""'"""'"""'""""""""'"""'""'"""""""'"""""""'""'"""'""""""""'""""""""'"""'"""""""'""""""""'"""'"""""""""'"""""""'"""""""'"""'"""""""""'""'"""""""'"""'"""""""'""'""'""'""'""'""'"""'""'""'"""""""'""'""'""'""'""'"""'"""""""'""""""""'"""'"""""""'""'""'""'""'""'"""'""""'"""""""""'"""""""""'""'"""""'"""""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'""""""'"""""""'""'"""'""""""""'"""""""'"""""""'""'"""'"""'"""""""""'"""""""'""'""'""'""'""'"""""""'""'""'"""'"""'"""""""""'""'"""""""'"""'"""'""""""""'"""'""""""'"""""""'""'"""'""""""""'"""""""'"""""""'""'"""'"""'"""""'"""""""'""""""'""'""'"""'""'"""""""'""'""'"""'"""'""""'""""'"""""'""""""'"""""""'""'"""'""""""""'"""""""'"""""""'""'"""'""""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'"""'"""""'"""""""'""""""'""'""'"""'""'"""""""'""'""'"""'""""""'"""""""'""'"""'""'"""""""'"""""""'""'"""'"""""""""'""'"""""""'"""'""""""'""""""""'""""""""'""""""""'""""""""'"""""""'""'""'"""'"""'"""'"""'"""""""""'"""""'"""""""'""""""'""'"""'""'"""""""'""'"""'"""""""'""'""'""'""'"""'"""'"""""""""'"""""""'""'""'""'"""'"'"""""""'""""""""'"""'"""'"""""""""'""""""""'""""""""'""""""""'"""""""'"""""""'"""'"""""""""'"""""""'""'""'""'"""'"'""'""'""'""'""'""'""'""'""'"""'"""'""""""'"""""""'"""'""""""""'""""""'""'""'""'"""'"""""'"""""""'""""""'""'""'"""'""""""""'"""""""'""'""'"""'""""""'"""""""'"""'""""""""'"""""""'"""""""'"""'"""

## Explanation

I’m going to walk you through how the program works by showing you how it processes the specific input `202,100,1`.

In the beginning, we construct a few values that we will need later — mostly the ASCII codes of the characters we will output.

As you can see, `'8'` and `'.'` are already available. `'|'`, however, is really 124, not 14. We use a while loop to add twice the temporary value in slot #1 onto it to get 124 (which is 14 + 55×2, because the while loop runs for 56−1 = 55 iterations). This saves some bytes because large integer literals like 124 are really long. In the following diagram, I show the location of every variable the program uses.

Next, we want to input all the characters and store them on the tape starting at cell #12 (*p* is the running pointer for this). At the same time, we want to know how long the longest number is (how many digits). To achieve this, we keep a running total *in unary* going leftwards starting at cell #−1 (we use *q* as the running pointer). After the first input number (`202`), the tape now looks like this:

You will have noticed that the numbers are off by 4. Well, when we first input them, they are their ASCII values, so they’re “off” by 48 and the comma is 44. For each character, we copy the 46 from `'.'` into *r* and then subtract it with a while loop (which subtracts 45) and then we add 1. We do that so that the comma (our separator) is 0, so we can use a conditional to recognize it.

Also, you will have noticed that we leave cell #11 at 0. We need that to recognize the boundary of the first number.

The next character will be a comma, so we store a 0 in #15, but of course this time we don’t advance *q*. Instead, we set *q* back to 0 and start “overwriting” the 1s we’ve already placed.

After all the remaining characters are processed, we get this:

As you can see, the 1s written by *q* now indicate (in unary) the length of the longest number.

We now use a while loop to move *q* to the very left, and then place another pointer there which I will call *r2*. The purpose of *r2* will become clear later.

At this point, let me clarify the terminology that I will use throughout this.

* By **number**, I mean one of the input numbers that are separated by commas. In our example, they are 202, 100 and 1.
* By **digit**, I mean a single digit in a specific one of the numbers. The first number has 3 digits.
* By **place**, I mean the ones place, tens place, hundreds place, etc. So if I say “the digits in the current place”, and the current place is the ones place, those digits are 2, 0, and 1 in that order.

Now back to our regular programming. The entire rest of the program is a big loop that moves *q* forward until it reaches cell #0. Each of the cells along the way represents a place, with the ones place on the far right, and *q* will start at the most significant. In our example, that is the hundreds place.

We proceed by incrementing the cell *q* points at (that is, *\*q*).

We are now at “stage 2” for the hundreds place. In this stage, we will find out what the largest digit is among all the digits in the hundreds place. We use the same unary counting trick for this, except this time the pointer is called *r* and the pointer *r2* marks its starting position to which we need to reset it every time we move on to the next number.

Let’s start with the first number. We begin by setting *p* to 11 (the hard-coded starting position of all the numbers). We then use a while loop to find the end of the number and set *p2* there to mark the position. At the same time, we also set *q2* to 0:

Don’t be distracted by the fact that *q2* is pointing into the vars. We don’t have a padding of a blank cell there because we can detect cell #0 simply because it’s number zero.

Next, we go through the current number by decrementing *p* and *q2* together until *\*p* is zero. At each place, the value of *\*q2* tells us what we need to do. 1 means “do nothing”, so we keep going. Eventually we encounter the 2 in cell #−3. Every time *\*q2* is not equal to 1, *q2* is always equal to *q*.

As I already stated, stage 2 is “determine the largest digit in this place”. So we set *r* to *r2*, use a while loop to decrement *\*p* and move *r* leftwards and fill the tape with 1s, and then use another while loop to move *r* back to the right and increment *\*p* again to restore the value. Remember that every while loop runs for one fewer iteration than the value we use it on; because of this, the number of 1s written will be 3 more (rather than 4 more) than the digit value, and the final value stored back in *\*p* will be 2 more. Thus, this has effectively decremented *\*p* by 2.

After that, we set *p* to the value of *p2* and then we do all that again. For the second time, set *q2* to 0, find the end of the number by moving *p* to the right, and then go through the digits of this number by decrementing *p* and *q2* together. Once again we will encounter the 2 in cell #−3 and write that many 1s left of *\*r*.

In the case of the third number, we end up doing nothing because it doesn’t have a hundreds place (so *q2* never reaches *q*), but that’s OK because that doesn’t affect the calculation of the maximum digit value.

We also set the cell *\*(r − 4)*, which I’ve marked with an unlabeled arrow here, to 1 (even though it’s already at 1). I’m not going to tell you why yet, but maybe you’ve already guessed?

The next increment of *\*q* takes us to stage 3, which is “subtract the maximum digit from all digits in the current place”. As before, we reset *p* to 11 and *q2* to 0 and then go through all the numbers just like we did in the previous stage; except this time, *\*q* = 3 instead of 2. Every time *q2* meets *q* and *p* is in a hundreds place, we use a while loop to decrement *\*p* as many times as there are 1s in the block left of *\*r2* (5 in our example) by using *r* as a running pointer. We actually decrement it once more than that so that the largest digit ends up at −2, for a reason that will become clear later:

After we’ve processed all the numbers, we are now at the end of stage 3. Here we perform two singular things.

* First, we *also* subtract the size of the *r*-block (plus 1) from *\*q*, but using the *r2* pointer, which leaves it on the left. *\*q* becomes negative this way. In our case, the *r*-block has five 1s, so *\*q* becomes −3.
* Second, we set a variable *out* to a non-zero value to indicate that we are now entering the output stage. (Technically, the fact that *\*q* is negative already indicates the output stage, but this is too difficult to check for, hence the extra variable.)

You now understand that we keep going through the numbers, find the current place (indicated by the non-1 value of *\*q*) within each number, and do something depending on the value of *\*q*. We see that *\*q* is first incremented to 2 (= calculate maximum digit value), then 3 (subtract maximum digit value from every digit in this place) and then we subtract from it to make it negative. From there, it will continue to go up until it reaches 1, thus restoring the value that means “do nothing”. At that point, we move on to the next place.

Now, when *\*q* is negative, we’re outputting. *\*q* is at exactly the right value so that we will output the right number of rows of characters before it reaches 1; if the largest digit is 2, we need to output 3 rows. Let’s see what happens at each value of *\*q*:

* ***\*q* = −2:**
    + For the first number, *\*p* is −2, which indicates that we need to output a `'.'` (dot) or a `':'` (colon). We decide which by looking at *q*: if it’s −1, we’re in the ones place, so output a `':'` (which we calculate as `'8'`+2), otherwise a `'.'`.
    + For the second number, *\*p* is −3. Anything that is not −2 means we output a `'|'` (pipe) and then increment the value. This way it will reach −2 in the right place and then we output `'.'`s/`':'`s for the rest of that digit.
    + In each case, we also set a variable *pd* to 0 *before* we process the number, and set *pd* (= “printed”) to a non-zero value to indicate that we have printed a character.
    + For the third number, no processing occurs because the third number does not have a hundreds place. In this case, *pd* will still be 0 after processing the number, indicating that we still need to output a `'|'` (but only if *out* is non-zero, because otherwise we’re still in stage 2 or 3).
    + After processing all numbers, if *out* is non-zero, output a newline. Note that we need the *out* variable so that we don’t output the newline in stage 2 or 3.
* ***\*q* = −1:** Same as before, except that *\*p* is −2 for both the first two numbers, so both output a `'.'` (and the third outputs a `'|'` as before).
* ***\*q* = 0:** When *\*q* is 0, this means “do nothing if we’re in the ones place, otherwise output a row of `'|'`s regardless of *\*p*”. This way we get the padding between the digits.

Now we increment *q* to move on to the next place, the tens place, and increment *\*q* there. At the beginning of Stage 2, the tape looks like this:

Then we perform Stage 2 just as before. Remember this effectively subtracts 2 from every digit in this place and also leaves a unary number left of *\*r2* indicating the maximum digit. We leave the previous unary number alone and just keep extending the tape to the left; it would only cost unnecessary extra code to “clean up”. When we’re done and we increment *\*q*, at the start of Stage 3 the tape is now:

Actually, this is a lie. Remember earlier where I said we set *\*(r − 4)* to 1 and I didn’t tell you why? Now I’ll tell you why. It’s for cases like this one, where the largest digit is in fact 0, meaning *all* the digits in this place are 0. Setting *\*(r − 4)*, indicated by the unlabeled arrow above, to 1 extends the unary number by 1, but only in this special case. This way we pretend as if the largest digit was 1, which means we will output one extra row.

After Stage 3 (subtract maximum digit from all digits in the current place), including the extra step that makes *\*q* negative, the tape looks like this. Last time the biggest digit was represented by −2 in the *\*p* block, but this time they’re all −3 because they’re all actually zeroes but we’re pretending as if the maximum digit was a 1.

Now let’s see what happens as *\*q* progresses towards 1:

* When *\*q* = −1, the *\*p* values are all −3, which means we output `'|'`s and increment them.
* When *\*q* = 0, we output `'|'` because that’s what we always do when *\*q* = 0, regardless of *\*p*.

Thus, we get two rows of pipes.

Finally, we move *\*q* to the one’s place. This one gets interesting because we need to output `':'`s if the actual digit is anything but 1, but an `'8'` if it’s 1. Let’s see how the program proceeds. First, we increment *\*q* to initiate Stage 2:

After Stage 2 (“calculate maximum digit value”), we’re left with this:

After Stage 3 (“subtract maximum digit value from all digits in current place”) the tape looks like this:

Now let’s go through each iteration of *\*q* in turn:

* ***\*q* = −2:**
    + First number: already at −2, so output a `':'` (rather than a `'.'` because *q* = −1).
    + Second number: at −4, so output a `'|'` and increment.
    + Third number: at −3, so output a `'|'`. However, this time, instead of incrementing, a special case triggers. *Only* if we’re outputting the last place (*q* = −1), *and* we’re in the second-last row for that (*\*q* = −2), *and* the digit is actually a 1 (*\*p* = −3), *then* instead of incrementing it to −2, we set it to −1. In other words, we use −1 as a special value to indicate that in the next iteration, we will need to output `'8'` instead of `':'`.
* ***\*q* = −1:**
    + First number: already at −2, so output a `':'`.
    + Second number: at −3, so output a `'|'`. The special condition does not trigger because *\*q* is no longer −2. Therefore, increment.
    + Third number: at −1, so output `'8'`.
* ***\*q* = 0:** Ordinarily, we would output the padding row of `'|'`s here, but in the special case where we’re in the ones place (*q* = −1), we skip that.

After this, *q* is incremented to 0 and the big while loop ends.

Now you know how an input like `202,100,1` works. However, there’s one more special case that we still haven’t covered. You may remember that while we were processing the last place, when *\*p* was −3 we set it to −1 for the `1` (instead of incrementing it to −2) so that the next iteration would output an `'8'` instead. This only works because we have an iteration in which *\*p* is −3 and we make a decision as to whether to increment it or set it to −1. We *do not* have such an iteration if *all* of the digits in the ones place are 0 or 1. In such a case all the *\*p* values for the 1s would *start out* at −2; there is no opportunity to decide to set it to −1 *rather than to increment it from −3*. Because of this, there is another special-casing condition inside Stage 3 (“subtract maximum digit from every digit in the current place”). I claimed that after subtracting the maximum digit value from every digit (at which point the maximum digit is at −1), we just decrement it once more, but actually there’s a condition on that which goes as follows:

If the digit we’re looking at is equal to the maximum digit in this place (*\*p* = −1), *and* this place is the ones place (*q* = −1), *and* the maximum digit is 1 (*\*(r + 5)* = 0, i.e. the unary block at the very left is only 5 cells long), *only then* we leave *\*p* at −1 to indicate that the only iteration of the output must output an `'8'`. In all other cases we decrement it once more.

Done. Happy new year!

* **Edit 1 (3183 → 3001):** Some Happy New Year golfing! I managed to get rid of the variables *p2* and *r2* entirely! *p* now races back and forth to keep finding the beginning and end of numbers, but it seems to be shorter in code. I tried to get rid of *q2* as well, but I couldn’t make the code shorter that way.

I also found a few more places where I could apply typical Unreadable golfing tricks like re-using the last value of a while loop. To give you an example, instead of

```
while *(++p) { 1 }         // just increment p until *p is 0; the 1 is a noop
if (pd) { x } else { y }   // where pd is a variable

```

I can save the `'""""` (do the first, then the second) and the `'"""` (constant 1) by writing it in a way that is kind of like

```
if (while *(++p) { pd }) { x } else { y }

```

Of course, this only works if I know that the while loop will run for at least one iteration, but if it does, its return value is *pd* so I can use that as the condition for the if.
> 24 votes

# Answer
# Python 3, ~~624~~ ~~598~~ ~~595~~ ~~574~~ ~~561~~ ~~535~~ ~~532~~ ~~527~~ ~~525~~ ~~426~~ ~~345~~ ~~328~~ ~~324~~ ~~294~~ ~~288~~ ~~286~~ ~~283~~ ~~280~~ ~~267~~ ~~265~~ ~~255~~ ~~251~~ ~~245~~ ~~238~~ ~~235~~ ~~234~~ ~~230~~ ~~228~~ ~~236~~ 244 bytes

```
z=input().split();v=max(map(len,z));d=''.join(i.zfill(v)for i in z);x=['']*len(z)
for k,c in enumerate(d):j=k%v;m=int(max(d[j::v]));c=int(c);x[k//v]+="|"*(m-c+(2>v)+(j>0)+0**(m+(j>v-2)))+":8."[(c<2)|-(j<v-1)]*c
for r in zip(*x):print(*r,sep='')

```

Try it online!

Well, since this question needed an answer, I have provided one here, where the input should be a space-separated string of numbers, such as `"204 1"`. Boy, is it a long one. Any golfing suggestions (or better answers) are welcome.

**Edit:** Bytes saved by mixing tabs and spaces.

**Edit:** I saved a *lot* of bytes by changing how I obtained the digits of a number (make a list from the zero-padded string of the number, then in the body of the code, transpose to get hundreds digits, ten digits, etc.)

**Edit:** And I saved some more by incorporating that last `:8` loop into the main quipu loop. ~~Now if only I could figure out why `b=d[j*v+i]==m(d[i::v])` won't work.~~ Figured it out and the solution takes too many bytes. (Also the byte count dropped because somehow the tabs turned back into four spaces. It was probably the code block formatting on this site)

**Edit:** I reorganized how made the quipus. Now it creates one strand at a time, then transposes for printing.

**Edit:** Turned my answer back into a Python 3 program to save some more bytes.

**Edit:** I found a bug in my code that made it so that it was not printing zeroes in the middle of numbers correctly (see test case `204 1` above). In fixing this, I managed to golf it :)

**Edit:** I changed the printing to save 10 bytes. And I put all of the old byte counts back, just because.

**Edit:** Golfed the assignment of `v` using `map` for four bytes. Credit to CarpetPython, as I got the idea from their answer here.

**Edit:** Turned the middle "for loop inside a for loop", into just one for loop for six bytes.

**Edit:** Now using `enumerate`. No longer using `l=len(z)`. Turned the ternary `if-else` into a list ternary. See below for details.

**Edit:** Sp3000 suggested an edit to `print` and an edit to the ternary condition that saved a byte each.

**Edit:** +6 bytes fixing a bug where the code did not follow rule 7. +8 more bytes in continuing to fix this bug. O bytes from more bug fixes.

**Ungolfed:**

```
s = input()
z = s.split()
v = max(map(len, z))                # the amount of digits of the largest number
d = ''.join(i.zfill(v) for i in z)  # pad zeroes until every number is the same length
                                     # then join the numbers into one string
x = ['']*len(z)                     # a list of strings for the output, one for each number

for k,c in enumerate(d):          # for every digit in every number
    i,j = divmod(k, v)            # i is the index of the number we're on
                                   # j is the index of the digit of the number we're on
    m = int(max(d[j::v]))         # the largest of all the digits in the j-th place
    c = int(c)                    # the digit in j-th place of the i-th number
    x[i] += "|"*(m-c+(j>0)+0**(m+(2>v)*(j>v-2)))
                                  # pad | to size m-c, until the knots are correctly spaced
                                  # add a | if all inputs are single-digit numbers
                                  # add a | if j>0, if it's not at the start, as delimiters
                                  # add a | if the maximum is 0 and it's *NOT* the ones digit
    x[i] += ":8."[(c<2)|-(j<v-1)] * c
    # this is essentially the following code
    # if j<v-1:
    #     x[i] += "."*c      # . knots if not in the units place
    # else:
    #     if c == 1:
    #         x[i] += "8"*c  # 8 knots for ones in the units place
    #     else:
    #         x[i] += ":"*c  # : knots for something else is in the units place

for r in zip(*x):       # transpose so all the rows (the quipu strings) now hang down
    print(*r, sep='')    # join the strings together at each knot
                         # and print each on a separate line

```
> 8 votes

# Answer
# Javascript (ES6) ~~750~~ ~~744~~ ~~690~~ ~~604~~ ~~498~~ ~~346~~ ~~245~~ 234 bytes

I'm new to PPCG and thought I might give this one a try thinking it was rather simple. Boy was I wrong!! I've been working on it for a while and I have **a lot of golfing** to do...
Suggestions are encouraged! - although making sense of this won't be an easy task.

Outputs ropes when the input is an array of numbers (eg: `[204, 1]` ).

```
a=>(o=m=s="",l=a.map(n=>(s+="|",l=(n+"").length)>m?m=l:l),h=[],a=a.map((n,i)=>[..."0".repeat(m-l[i])+n].map((d,j)=>d<h[j]?d:h[j]=d)),h.map((n,i)=>{i?o+=s+`
`:0;for(j=n;j--;o+=`
`)a.map(d=>o+="|.:8"[d[i]-j<1?0:i<m-1?1:d[i]-1?2:3])}),o)

```

## Explanation

```
a=>(

  o=m=s="",                      // m = max number of digits in a number, s = separator string
  l=a.map(n=>(                   // l = lengths of each number
      s+="|",                    // set the separator string
      l=(n+"").length                 // convert each number to a string
    )>m?m=l:l                    // get max length
  ),
  h=[],
  a=a.map((n,i)=>
    [..."0".repeat(m-l[i])+n]    // add leading 0s to make all same length
    .map((d,j)=>d<h[j]?d:h[j]=d) // set each digit of h to max
  ),

  h.map((n,i)=>{
    i?o+=s+`
`:0;
    for(j=n;j--;o+=`
`)
      a.map(d=>
        o+=
          "|.:8"[
            d[i]-j<1?0
            :i<m-1?1
            :d[i]-1?2:
            3
          ]
      )
  }),
  o
)

```

## Example

**Input:** Array of numbers: `[4,8,15,16,23,42]`
**Output:**

```
|||||.
|||||.
||||..
||....
||||||
|:||||
|:||||
|:|:||
|:::||
::::||
:::::|
::::::
::::::

```
> 8 votes

# Answer
# Mathematica ~~436 453 357 352~~ 347 bytes

```
t=Transpose;y=ConstantArray;a=Table;
g@j_:=(s=t[PadLeft[#,Max[Length/@i]]&/@(i=IntegerDigits@#)]&;p_~u~o_:=(m=Max@p;c=If[o==-2,":","."];w=If[o==-2,"8","."];p//.{0->a["|",Max@{1,m}],1->Join[a["|",{m-1}],{w}],n_/;MemberQ[2~Range~9,n]:>Join[y["|",m-n ],c~y~n]});t[Join@@@t@Join[u[#,0]&/@Most@#,u[#,-2]&/@{#[[-1]]}]]&[Riffle[(s@j),{a[0,Length@j]}]]//Grid)

```

The above

* Breaks up each integer into a list of digits, using `IntegerDigits`; pads each number with zeros to the left (to ensure equal spacing); each input number, now decomposed into digits, corresponds to a row of an array; each column represents a place value. Array is transposed.
* Replaces digits with a list of knots with padding. A slightly different pattern-matching routine is used for the units.

---

**Example**

```
g[Range[0, 50]]

```
> 4 votes

# Answer
# C, 238 235 bytes

Relying heavily on the C preprocessor to make the code as short as possible. As a side effect, also makes it pretty much unreadable.

```
#define l strlen(a[i])
#define d l<k||a[i][l-k]-48
#define m(e) for(i=1;a[i];e<=r?i++:r++);
#define p(e) {m(!putchar(e?'|':k>1?46:d<2?56:58))puts("");}
k,r;main(int i,char**a){m(l)for(k=r,r=1;k;r=k>1){m(d)for(;r;r--)p(d<r)if(--k)p(1)}}

```

On Ubuntu 14.04, you can compile the code with a straightforward `gcc quipu.c` (please ignore the warnings). An example of running the executable:

```
$ ./a.out 1 2 3 2 1
||:||
|:::|
8:::8

```

Tested against all OP's test cases.

Ungolfed source code:

```
// Standard library; leaving out the includes still gives executable code despite the warnings.
#include <stdio.h>
#include <string.h>

// 4 preprocessor macros.
// Note: some of these actually make use of the fact that parentheses have been left out

// l: length of argument i
#define l     strlen(a[i])

// d: shorthand for a digit
#define d     l<k || a[i][l-k]-'0'

// m: loop across all arguments; calculates r as the maximum of expression e
#define m(e)  for (i=1; a[i]; e<=r ? i++ : r++);

// p: prints one line of output
// note: intentionally does not use the r++ code branch of m;
//       putchar always returns a non-zero number here, so !putchar is zero,
//       which is always <=r (because r is never negative)
// note: the semicolon after m(...) is redundant;
//       the definition of m already contains a semicolon
// note: puts("") outputs a newline
#define p(e)  { m(!putchar(e ? '|' : k > 1 ? '.' : d < 2 ? '8' : ':')); puts(""); }

// k: knot position; 1 for units, 2 for tens, 3 for hundreds...
int k;

// r: input and output value for m
// note: the first time we call m, we need r to be zero;
//       by defining it outside main, it is automatically initialized as such
int r;

// function main
// note: parameter i (normally named argc by convention) is not needed
//       (the last element of argv is known; it is followed by a NULL pointer)
//       but we cannot leave it out (otherwise we cannot access argv)
//       so it serves as a local variable (to loop through arguments; see m)
// note: parameter a (normally named argv by convention)
//       is the array of arguments (starting from index 1)
int main(int i, char **a)
{
    // Determine the longest argument; store its length in r.
    // This is the number of knot positions to consider.
    m(l)

    // Iterate k through the knot positions from top to bottom.
    // Note: k > 0 has been abbreviated to k.
    // Note: for each iteration, we also initialize r with either 0 or 1.
    //       0 = suppress printing when all knots are zero
    //       1 = always print, even when all knots are zero
    for (k = r, r = 1; k > 0; r = k > 1)
    {
        // Determine the highest digit at this knot position.
        // Note: due to the absence of parentheses, d mixes up with <=r into:
        // (l < k) || (a[i][l-k]-'0' <= r)
        m(d)

        // Count the digits down.
        for (; r; r--)
        {
            // Print a single line of output.
            // When d (the digit in the current strand) is less than the counter,
            // then print a '|', otherwise print a knot.
            p(d < r)
        }

        // Decrement k (go to next knot position).
        // If this was not the last iteration...
        if (--k > 0)
        {
            // Print separator line.
            p(1)
        }
    }

    // Return exit code zero; redundant.
    return 0;
}

```
> 4 votes

# Answer
# R - 446 444

I see there is no R solution yet, so here is one. The function takes a vector with integers.

```
function(x){r=nchar(max(x));c=length(x);m=matrix(0,r,c);for(i in 1:c){t=as.numeric(strsplit(as.character(x[i]),"")[[1]]);m[(r+1-length(t)):r,i]=t};Q=c();for(i in 1:r){d=m[i,];z=ifelse(max(d)>0,max(d),1);q=matrix("|",z,c);for(j in 1:c){v=m[i,j];if(i==r){if(v==1)q[z,j]=8;if(v>1)q[(z-v+1):z,j]=rep(":",v)};if(i<r){if(v>0)q[(z-v+1):z,j]=rep(".",v)}};if(i!=1&sum(d)>0)q=rbind(rep("|",c),q);Q=rbind(Q,q)};for(i in 1:nrow(Q))cat(Q[i,],sep="",fill=T)}

```

## Ungolfed

```
# Some test data
test <- c(201, 0, 100, 222, 53)

# Define function
quipu <- function (x) {

    # Create matrix with a row for each digit and a column for each number
    r=nchar(max(x));c=length(x);m <- matrix(0,r,c)
    for(i in 1:c) {
        t=as.numeric(strsplit(as.character(x[i]),"")[[1]])
        m[(r+1-length(t)):r,i]=t
    }

    # Loop through each row (digit) starting at the top of the quipu
    Q=c() # Empty matrix to store quipu
    for(i in 1:r){

        d=m[i,]
        z=ifelse(max(d)>0,max(d),1)
        q=matrix("|",z,c)

        # Loop through each column (number in the vector) starting at the leftmost quipu
        for(j in 1:c){

            # The digit
            v=m[i,j]

            # If it is the last segment of the quipu
            if(i==r){
                if(v==1){q[z,j]=8} # If unit digit =1
                if(v>1){q[(z-v+1):z,j]=rep(":",v)} # If unit digit >1
            }

            # If it is not the last segment of the quipu
            if(i<r){
                if(v>0){q[(z-v+1):z,j]=rep(".",v)} # If non-unit digit >0
            }
        }

        # Add segment to Q
        if(i!=1 & sum(d)>0){q=rbind(rep("|",c),q)}
        Q=rbind(Q,q)
    }

    # Print quipu
    for(i in 1:nrow(Q)) {cat(Q[i,], sep="", fill=T)}
}

# Test
quipu(test)

```
> 1 votes

# Answer
# APL (Dyalog Unicode), ~~160~~ ~~137~~ ~~132~~ ~~128~~ ~~123~~ ~~117~~ ~~126~~ ~~119~~ 116 bytes

I sort of wrote this in a frenzy while unable to sleep tonight, so please forgive me if I skip the explanation, and miss any bugs or golfing opportunities. I'll take another look at this after I've gotten some sleep.

**Edit:** ~~Turns out this doesn't for an input of just `0`. Will fix soonest.~~ -23 bytes from bug fixing! -5 bytes from removing no-longer-used variables. -4 bytes from using parts of the approach used in Leaky Nun's excellent Pyth answer (Sidenote: this answer is now exactly twice as long as that answer :D). -5 bytes from rearranging the result matrix mid-computation. -6 bytes from slimming down the generation of the result matrix even further. +9 bytes bug fixing. 0 bytes from more bug fixing. -7 bytes from rearranging how to handle the ones digit special case. -3 bytes from continued rearranging.

```
{⎕IO←0⋄m←⊖↓10⊥⍣¯1⊢1,⍵⋄1↓⊃⍪/⌽{w←1↓⊃m[⍵]⋄M+←1+0*((1≠≢m)∧⍵=0)+M←⌈/w⋄⊃,/⍵{M 1⍴((M-⍵)/'|'),⍵/'.'(':8'[1=⍵])[0=⍺]}¨w}¨⍳≢m}

```

Try it online!

**Explanation**

```
quipu←{
    ⎕IO←0         ⍝ Set to 0-indexing
    nums ← 1,⍵    ⍝ Append a 1 so that when converting in the next line,
                  ⍝ we always get a matrix, not a vector
    digit_list ← ⊖ ↓ 10⊥⍣¯1⊢ nums    ⍝ All the digits in each digit place, reversed

    ⍝ For each digit in each digit place, create knots
    1↓⊃⍪/⌽{    ⍝ After generating knots, these instructions clean up the result
        q ← ⍵
        w ← 1↓ ⊃ digit_list[⍵]    ⍝ 1↓ drops the 1 we appended before
        M +← 1+ 0* ((1 = ≢digit_list) ∧ (⍵ ≠ 0)) + M ← ⌈/w
        ⍝ M is the number of knot spaces (including delimiters) needed
        ⊃,/{     ⍝ ,/ concatenates the knots
            padding ← ((M-⍵) 1)⍴'|'
            knots ← ⍵ / ('.' (':8'[1=⍵]))[q=0]
            (M 1) ⍴ knots ⍪ padding   ⍝ Turns the knots into a column vector
                                      ⍝ of shape M by 1
        }¨w
    }¨⍳≢digit_list
}

```
> 0 votes

---
Tags: code-golf, number
---


# Question
Title: Draw a fully-rendered path from direction changers
(Note: this challenge is distinct from my other challenge (Draw a path made from direction changers) because of it's rendering of direction (horizontal or vertical), crossing points and single or double paths.)

---

Let's start with a frame drawn in Ascii characters. For this challenge it will always be 20 characters wide and 10 characters high.

```
+--------------------+
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
+--------------------+

```

It will begin populated with one of a number of objects:

```
| Name       | Char | Description                                    |
| Source     | *    | This will send a path to the North             |
| East       | >    | Any path meeting this will turn to the East    |
| West       | <    | Any path meeting this will turn to the West    |
| North      | ^    | Any path meeting this will turn to the North   |
| West       | V    | Any path meeting this will turn to the South   |

```

Your job will be to start with the objects above, and populate the grid with these characters, which will display the path they describe.

```
| Name                   | Char | Description                                                                   |
| Vertical path          | |    | The path is travelling North or South                                         |
| Horizontal path        | -    | The path is travelling East or West                                           |
| Double Vertical path   | N    | The path is doubled and is travelling North or South                          |
| Double Horizontal path | =    | The path is doubled and is travelling East or West                            |
| Crossing point         | +    | A North/South path and an East/West path have met                             |
| Double crossing point  | #    | A North/South path and an East/West path have met and one or both are doubled |

```

# Path drawing rules

When a path meets either the edge of the map or a source, it will stop there.

If a path meets a direction changer, they will go in it's direction, using the direction changer as a starting point, e.g.:

```
+--------------------+
|                    |
|                    |
|    >---------------|
|    |               |
|    |               |
|    |               |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

If a direction changer tells a path to go back the way it came, it will display a double path e.g.:

```
+--------------------+
|                    |
|                    |
|                    |
|    >====<          |
|    |               |
|    |               |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

If two paths cross, they will meet with a + symbol. E.g.:

```
+--------------------+
|        |           |
|        |           |
|        |           |
|    >---+-----------|
|    |   |           |
|    |   *           |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

If two paths cross, and one or both are doubled back, they will meet with a # symbol. E.g.:

```
+--------------------+
|        |           |
|        |           |
|        |           |
|    >===#===<       |
|    |   |           |
|    |   *           |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

If two paths meet the same direction changer from different directions, the ongoing path is merged (doubled up). E.g.:

```
+--------------------+
|         N          |
|         N          |
|       >-^-<        |
|       |   |        |
|       |   |        |
|       *   *        |
|                    |
|                    |
|                    |
|                    |
+--------------------+

```

Doubled paths are immutable, they can not be un-doubled or become any heavier than double paths.

# The rules

* It's code golf, try to write short code to do this.
* Input and output are agnostic, I don't really mind about strings, arrays of chars, trailing and leading space etc. as long as I can see the outcome.
* Standard loopholes etc.
* Use any language you like.
* Please include a link to an online interpreter.

# Test cases

## Simple

In:

```
+--------------------+
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|                    |
|    *               |
|                    |
|                    |
+--------------------+

```

Out:

```
+--------------------+
|    |               |
|    |               |
|    |               |
|    |               |
|    |               |
|    |               |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

## One turn

In:

```
+--------------------+
|                    |
|                    |
|    >               |
|                    |
|                    |
|                    |
|                    |
|    *               |
|                    |
|                    |
+--------------------+

```

Out:

```
+--------------------+
|                    |
|                    |
|    >---------------|
|    |               |
|    |               |
|    |               |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

## Spiral

In:

```
+--------------------+
|                    |
|                    |
|                    |
|  <                 |
|                    |
|    >  V            |
|                    |
|    *               |
|  ^    <            |
|                    |
+--------------------+

```

Out:

```
+--------------------+
|                    |
|                    |
|                    |
|--<                 |
|  |                 |
|  | >--V            |
|  | |  |            |
|  | *  |            |
|  ^----<            |
|                    |
+--------------------+

```

## Reflect

In:

```
+--------------------+
|                    |
|                    |
|                    |
|    >    <          |
|                    |
|                    |
|                    |
|    *               |
|                    |
|                    |
+--------------------+

```

Out:

```
+--------------------+
|                    |
|                    |
|                    |
|    >====<          |
|    |               |
|    |               |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

## Two Sources

In:

```
+--------------------+
|                    |
|                    |
|                    |
|    >               |
|                    |
|        *           |
|                    |
|    *               |
|                    |
|                    |
+--------------------+

```

Out:

```
+--------------------+
|        |           |
|        |           |
|        |           |
|    >---+-----------|
|    |   |           |
|    |   *           |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

## One Doubles Back

In:

```
+--------------------+
|                    |
|                    |
|                    |
|    >       <       |
|                    |
|        *           |
|                    |
|    *               |
|                    |
|                    |
+--------------------+

```

Out:

```
+--------------------+
|        |           |
|        |           |
|        |           |
|    >===#===<       |
|    |   |           |
|    |   *           |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

## Path Meets Source

(Note that the path ends at the source, and does not join the other path and double up)

In:

```
+--------------------+
|                    |
|                    |
|                    |
|                    |
|                    |
|    >   *           |
|                    |
|    *               |
|                    |
|                    |
+--------------------+

```

Out:

```
+--------------------+
|        |           |
|        |           |
|        |           |
|        |           |
|        |           |
|    >---*           |
|    |               |
|    *               |
|                    |
|                    |
+--------------------+

```

## Paths Merging

In:

```
+--------------------+
|                    |
|                    |
|       > ^ <        |
|                    |
|                    |
|       *   *        |
|                    |
|                    |
|                    |
|                    |
+--------------------+

```

Out:

```
+--------------------+
|         N          |
|         N          |
|       >-^-<        |
|       |   |        |
|       |   |        |
|       *   *        |
|                    |
|                    |
|                    |
|                    |
+--------------------+

```

## Full Spiral

In:

```
+--------------------+
|     >        V     |
|      >      V      |
|       >    V       |
|        >  V        |
|         >V         |
|         *          |
|        ^ <         |
|       ^   <        |
|      ^     <       |
|     ^       <      |
+--------------------+

```

Out:

```
+--------------------+
|     >--------V     |
|     |>------V|     |
|     ||>----V||     |
|     |||>--V|||     |
|     ||||>V||||     |
|     ||||*|||||     |
|     |||^-<||||     |
|     ||^---<|||     |
|     |^-----<||     |
|     ^-------<|     |
+--------------------+

```

## Let's Have Some Fun

In:

```
+--------------------+
|                    |
|                    |
|  V   V   V   V     |
|>                  <|
|^                  <|
|                  < |
|>                 ^ |
|                    |
|  * * * * * * * *   |
|*                  *|
+--------------------+

```

Out:

```
+--------------------+
|    |   |   |   |   |
|    |   |   |   |   |
|  V | V | V | V |   |
|>=#=#=#=#=#=#=#=#==<|
|^-#-+-#-+-#-+-#-+--<|
|--#-+-#-+-#-+-#-+-<||
|>-#-+-#-+-#-+-#-+-^||
|| N | N | N | N |  ||
|| * * * * * * * *  ||
|*                  *|
+--------------------+

```

## Almost all cells visited twice

In:

```
+--------------------+
|>                  V|
| >                V |
|  >              V  |
|   >V>V>V>V>V>V>V   |
|                    |
|   *>^>^>^>^>^>^    |
|  ^             <   |
| ^               <  |
| V<V              < |
|^<^<^              <|
+--------------------+

```

Out:

```
+--------------------+
|>==================V|
|N>================VN|
|NN>==============VNN|
|NNN>V>V>V>V>V>V>VNNN|
|NNN||NNNNNNNNNNNNNNN|
|NNN*>^>^>^>^>^>^NNNN|
|NN^=#===========<NNN|
|N^==#============<NN|
|NV<V#=============<N|
|^<^<^==============<|
+--------------------+

```

Happy Golfing :)

# Answer
> 9 votes
# JavaScript (ES6),  ~~201 197~~  195 bytes

Takes input as a matrix of characters. Outputs by modifying the input.

```
f=(m,X,Y,k,d)=>m.map((r,y)=>r.map((c,x)=>~(s=' -|=N+#^<V>',i=s.indexOf(c))?k&&x%21&&y%11?x-X-~-~-d%2|y-Y-~-d%2|k>>9||f(m,x,y,-~k,i>6?i-7:d,r[x]=s[(25464-11928*(d&1)+'6')[i]||i]):0:k||f(m,x,y,1)))

```

Try it online!

## How?

### Updating the matrix

We use the following lookup string \\$s\\$ to identify and write the characters from/into the matrix:

```
i =  0123456
s = ' -|=N+#^<V>'

```

NB: `*` is not included, so we have \\$i=-1\\$ in that case.

Characters with an index \\$i\\$ greater than \\$6\\$ are direction changers, which are immutable. For the other characters, we use two translation tables to update them according to the current direction.

For vertical moves:

```
' ' (0) + '|' = '|' (2)
'-' (1) + '|' = '+' (5)
'|' (2) + '|' = 'N' (4)
'=' (3) + '|' = '#' (6)
'N' (4) + '|' = 'N' (4)
'+' (5) + '|' = '#' (6)
'#' (6) + '|' = '#' (6)

```

And for horizontal moves:

```
' ' (0) + '-' = '-' (1)
'-' (1) + '-' = '=' (3)
'|' (2) + '-' = '+' (5)
'=' (3) + '-' = '=' (3)
'N' (4) + '-' = '#' (6)
'+' (5) + '-' = '#' (6)
'#' (6) + '-' = '#' (6)

```

Hence the character translation code:

```
r[x] = s[           // update r[x]:
  (                 //   build a lookup string:
    25464 -         //     use 25464 if d is even
    11928 * (d & 1) //     or 13536 if d is odd
    + '6'           //     coerce to a string and append a '6',
                    //     which gives '254646' and '135366' respectively
  )[i]              //   extract the i-th digit
  || i              //   or use i if it's undefined,
]                   //   which leaves the original character unchanged

```

### Preventing an infinite loop

There is no explicit loop detection. Instead, we take advantage of the fixed size of the frame and simply stop the recursion when the number of moves from the source is greater than \\$511\\$ with:

```
k >> 9

```

This is enough to visit each cell twice (\\$2\times20\times10=400\\$). Beyond that, the board is guaranteed not to change anymore. We can get close to this with a configuration like this one.

## Commented

```
f = (                          // f is a recursive function taking:
  m,                           //   m[] = input matrix
  X, Y,                        //   (X, Y) = current position
  k,                           //   k = number of moves from the source
  d                            //   d = current direction in [0..3]
) =>                           //       (counter-clockwise with 0 = North)
  m.map((r, y) =>              // for each row r[] at position y in m[]:
    r.map((c, x) =>            //   for each character c at position x in r[]:
      ~(                       //
        s = ' -|=N+#^<V>',     //     s = lookup string
        i = s.indexOf(c)       //     i = position of c in s
      ) ?                      //     if i is not equal to -1 (i.e. c is not '*'):
        k &&                   //       if this is not the first iteration
        x % 21 && y % 11 ?     //       and we're not located over a border:
          x - X - ~-~-d % 2 |  //         abort if x - X is not equal to dx
          y - Y - ~-d % 2 |    //         or y - Y is not equal to dy
          k >> 9 ||            //         or k is greater than 511
          f(                   //         otherwise, do a recursive call:
            m,                 //           pass m[] unchanged
            x, y,              //           pass the new position
            -~k,               //           increment k
            i > 6 ? i - 7 : d, //           update d to i - 7 if i > 6
            r[x] = …           //           update r[x] (see above)
          )                    //         end of recursive call
        :                      //       else:
          0                    //         do nothing
      :                        //     else (c = '*'):
        k ||                   //       unless this is not the first iteration,
        f(m, x, y, 1)          //       start a new path to the North
    )                          //   end of inner map()
  )                            // end of outer map()

```

# Answer
> 2 votes
# Java 8, ~~275~~ 268 bytes

```
m->{for(int r=200,R,C,k,d,v;r-->0;)if(m[R=r/20+1][C=r%20+1]==42)for(k=d=0;(v=m[R+=(d*2-1)%5%3][C+=d/2-d*2/5*2])!=42&R%11*(C%21)>0&k++<500;d=v==94?0:v==86?1:v==62?2:v==60?3:d)m[R][C]-=v==43?8:v==61&d<2?26:v==45?d<2?2:-16:v==78&d>1?43:v>99?d<2?46:81:v<33?d<2?-92:-13:0;}

```

-7 bytes thanks to *@ceilingcat*.

Some inspiration taken from @Arnauld's JavaScript answer (mainly the strategy of looping a max of 400 instead of keeping track of which paths were visited (at least) twice).

Input as a character-matrix. Will modify the input instead of returning a new one to save bytes.

Try it online.

**Explanation:**

```
m->{                     // Method with char-matrix parameter and no return-type
  for(int r=200,         //  Current row/column index of the outer loop
          R,C,           //  Current row/column indices of the inner loop
          k,             //  Counter of the current path
          d,             //  Direction (0=North; 1=South; 2=East; 3=West)
          v;             //  Current value
      --r>0;)            //  Loop `r` over the rows+columns in the range [200,0):
    if(m[R=r/20+1][C=r%20+1]==42)
                         //    If the current cell contains a '*':
      for(k=d=0;         //     Reset `k` to 0, and the direction to North
          (v=m[R+=(d*2-1)%5%3]
                         //     † Update the row `R`,
              [C+=d/2-d*2/5*2])
                         //     and the column `C`
                         //     Set `v` to the value at this new cell `R,C`
          !=42           //     Inner loop as long as this next value is not '*',
          &R%11*(C%21)>0 //     nor are we on a border of the matrix,
          &k++<500       //     nor are we stuck in an infinite loop:
          ;d=            //       After every iteration: update direction `d`:
             v==94?      //        If the current cell contains '^':
              0          //         Update the direction to 0 (North)
             :v==86?     //        Else-if the current cell contains 'V':
              1          //         Update the direction to 1 (South)
             :v==62?     //        Else-if the current cell contains '>':
              2          //         Update the direction to 2 (East)
             :v==60?     //        Else-if the current cell contains '<':
              3          //         Update the direction to 3 (West)
             :           //        Else (any other character):
              d)         //         Keep the direction the same
                         //      †† Update the character at the current `R,C` cell
                         //      based on the current value and direction:
        m[R][C]-=v==43?8:v==61&d<2?26:v==45?d<2?2:-16:v==78&d>1?43:v>99?d<2?46:81:v<33?d<2?-92:-13:0;}

```

*†: Go to the next coordinate:*

I'm using the directions: North: \\$0\\$; South: \\$1\\$; East: \\$2\\$; West: \\$3\\$.

The coordinate changes we have to do are therefore:

```
direction d | new R,C coordinate
------------+-------------------
0 (North)   | R-1,C
1 (South)   | R+1,C
2 (East)    | R,C+1
3 (West)    | R,C-1

```

The straight-forward implementations would be these:

```
R+=d<1?-1:d<2?1:0
C+=d>2?-1:d>1?1:0

```

But they have been golfed to this (the `/` are integer-division):

```
R+=(d*2-1)%5%3 // maps to: 0→-1; 1→1; 2→0; 3→0
C+=d/2-d*2/5*2 // maps to: 0→0; 1→0; 2→1; 3→-1

```

*†: Change the values:*

We have to do the following mappings:

The characters `*><^V#` will always stay the same in the matrix (and we don't even have to check the `*` anyway, since we already stop the inner loop if we encounter another one).
That leaves us with the following mappings of the remaining characters, depending on the direction \\$d\\$:

```
current char (codepoint) | direction d | next char (codepoint)
---------------------------------------+----------------------
+ (43)                   | any         | # (35)
<space> (32)             | 0 or 1      | | (124)
<space> (32)             | 2 or 3      | - (45)
| (124)                  | 0 or 1      | N (78)
| (124)                  | 2 or 3      | + (43)
- (45)                   | 0 or 1      | + (43)
- (45)                   | 2 or 3      | = (61)
N (78)                   | 0 or 1      | N (78) - unchanged
N (78)                   | 2 or 3      | # (35)
= (61)                   | 0 or 1      | # (35)
= (61)                   | 2 or 3      | = (61) - unchanged

```

I'm currently using the following, although this can definitely be golfed with some magic number tricks:

```
m[R][C]-=  // Subtract from the codepoint of the current value:
 v==43?    //  If it contains a '+':
  8        //   Change it to '#' by subtracting 8
 :v==61    //  Else if it contains a '=',
 &d<2?     //  and the direction is vertical (north/south):
  26       //   Change it to '#' by subtracting 26
 :v==45?   //  Else-if it contains '-':
  d<2?     //   If the direction is vertical (north/south):
   2       //    Change it to '+' by subtracting 2
  :        //   Else (it's horizontal (east/west) instead):
   -16     //    Change it to '=' by adding 16
 :v==78    //  Else-if it contains a 'N',
 &d>1?     //  and the direction is horizontal (east/west):
  43       //   Change it to '#' by subtracting 43
 :v>99?    //  Else-if it contains a '|':
  d<2?     //   If the direction is horizontal (north/south):
   46      //    Change it to 'N' by subtracting 46
  :        //   Else (it's vertical (east/west) instead):
   81      //    Change it to '+' by subtracting 81
 :v<33?    //  Else-if it contains a ' ' (space):
  d<2?     //   If the direction is vertical (north/south):
   -92     //    Change it to '|' by adding 92
  :        //   Else (it's horizontal (east/west) instead):
   -13     //    Change it to '-' by adding 13
 :         //  Else (it's any other character):
  0;       //   Keep it the same by subtracting 0

```

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


# Question
Title: Shortest implementation of a linked list, stack and queue
**Challenge**

Write the shortest program that implements the minimum requirements for a linked list, stack and queue.

**Minimum requirements**

* Functions that allow the user to add and remove elements from the linked list, stack and queue.
* Any data type can be added to the linked list, stack and queue (string, int, etc.).
* One special function (e.g. sort letters alphabetically).
* The program must work (compile without errors and operations and results should make sense in the context of linked lists, stacks and queues)!
* Lastly, this program must be hard-coded. Arrays, however, are allowed (please refer to the restrictions section).

**Winning criteria**

* Standard Codegolf rules.
* Number of characters based on the summation of characters for linked list, stack and queue.

**Restrictions**

* No trivial answers (i.e. 0 or 1 for a stack based language).
* You **are allowed** to write the program in any language **except** for stack-based languages (let me know if this is unfair).
* You cannot simply use the functions of another class. If a language (like Ruby) already has `push` and `pop` functions in arrays or any other class, you must write **your own** `push` and `pop` functions.

---

*Little blurb*: If this code golf challenge is too simple, I will add more requirements. I'm also open to any suggestions.

# Answer
## Haskell, 81 69 characters

```
data L a=N|a:~L a
N~:z=z:~N
(a:~b)~:z=a:~(b~:z)
r N=N
r(a:~z)=r z~:a

```

This code makes use of no preexisting functions at all. The push operation is `:~`, the enqueue operation is `~:`. Both pop and dequeue are via pattern match against `:~`. The extra operation `r` is reverse.

Stacks:

```
ex1 =
    let stack0 = N                      -- empty stack
        stack1 = 'a' :~ stack0          -- push 'a'
        stack2 = 'b' :~ stack1          -- push 'b'
        first :~ stack3 = stack2        -- pop
        second :~ stack4 = stack3       -- pop
    in mapM_ print [first, second]

```

```
λ: ex1
'b'
'a'

```

Queues:

```
ex2 =
    let queue0 = N                      -- empty queue
        queue1 = queue0 ~: 'x'          -- enq 'x'
        queue2 = queue1 ~: 'y'          -- enq 'y'
        queue3 = queue2 ~: 'z'          -- enq 'z'
        next0 :~ queue4 = queue3        -- deq
        next1 :~ queue5 = queue4        -- deq
        next2 :~ queue6 = queue5        -- deq
    in mapM_ print [next0, next1, next2]

```

```
λ: ex2
'x'
'y'
'z'

```

List reverse operation:

```
ex3 =
    let list = "alpha" :~ ("beta" :~ ("gamma" :~ N)) -- a list
        tsil = r list                   -- reverse the list
        native N = []                   -- convert to native list
        native (a:~z) = a : native z    -- for easy printing
    in mapM_ (print . native) [list, tsil]

```

```
λ: ex3
["alpha","beta","gamma"]
["gamma","beta","alpha"]

```
> 4 votes

# Answer
## Ruby, 123

```
class S
def initialize
@a=[]
end
def u n
@a[@a.size]=n
end
def o
@a.slice! -1
end
def s
@a.slice!0
end
def j x
@a*x
end
end

```

Example:

```
s = S.new     # initialize
s.u 5         # push 5
s.u 10        # push 10
s.u [1,2,3]   # push [1,2,3]
s.u "test"    # push "test"
s.u "test2"   # push "test2"
puts s.s      # shift - queue behaivior (remove and return first element, 5)
puts s.o      # pop - stack behaivior (remove and return last element, "test2")
puts s.j ", " # join - special behavior (join elements with argument, "10, 1, 2, 3, test")

```
> 1 votes

# Answer
# C, 659 bytes

**Try Online**

```
typedef M;typedef struct M{int d;M*n;M*p;}Q;typedef struct{Q*f;Q*e;}L;Q*t;x;
Q*F(L**l){return*l?(*l)->f:0;}
Q*E(L**l){return*l?(*l)->e:0;}
N(Q**t){*t=*t?(*t)->n:0;}
P(Q**t){*t=*t?(*t)->p:0;}
A(L**l,int d){Q*t=(Q*)malloc(sizeof(Q));t->d=d;if(*l)(*l)->f->p=t,t->n=(*l)->f,(*l)->f=t;else(*l)=(L*)malloc(sizeof(L)),(*l)->f=t,(*l)->e=t;}
B(L**l){if(*l)t=(*l)->f,(*l)->f=t->n,(*l)->f->p=0,x=t->d,free(t);if(!(*l)->f)free(*l);return x;}
C(L**l,int d){t=(Q*)malloc(sizeof(Q));t->d=d;if(*l)(*l)->e->n=t,t->p=(*l)->e,(*l)->e=t;else (*l)=(L*)malloc(sizeof(L)),(*l)->f=t,(*l)->e=t;}
D(L**l){if(*l)t=(*l)->e,(*l)->e=t->p,(*l)->e->n=0,x=t->d,free(t);if(!(*l)->e)free(*l);return x;}

```

**Detailed** *github*

```
typedef _LNode; typedef struct _LNode{ void* d; _LNode* n; _LNode* p; } LNode;
typedef _List; typedef struct _List{ LNode* f; LNode* e; int size; } List;

LNode* list_begin(List** l){ return *l?(*l)->f:0; }
LNode* list_end(List** l){ return *l?(*l)->e:0; }

void list_iterator_next(LNode** t){ *t = *t?(*t)->n:0; }
void list_iterator_prev(LNode** t){ *t = *t?(*t)->p:0; }

int list_size(List** l){ return *l?(*l)->size:0; }

void list_push_front(List** l, void* d)
{
    LNode*t = (LNode)malloc(sizeof(LNode));
    t->d = d;

    if(*l)
        (*l)->f->p = t,
        t->n = (*l)->f,
        (*l)->f = t;
    else
        (*l)=(List*)malloc(sizeof(List)),
        (*l)->f = t,
        (*l)->e = t;

    (*l)->size++;
}

void list_push_back(List** l, void* d)
{
    LNode*t = (LNode)malloc(sizeof(LNode));
    t->d = d;

    if(*l)
        (*l)->e->n = t,
        t->p = (*l)->e,
        (*l)->e = t;
    else
        (*l)=(List*)malloc(sizeof(List)),
        (*l)->f = t,
        (*l)->e = t;

    (*l)->size++;
}

void* list_pop_front(List** l)
{
    LNode* t = 0;
    void* d = 0;

    if(*l)
        t = (*l)->f,
        (*l)->f = t->n,
        (*l)->f->p = 0,
        d = t->d,
        free(t),
        (*l)->size--;

    if(!(*l)->f) free(*l);

    return d;
}

void* list_pop_back(List** l)
{
    LNode* t = 0;
    void* d = 0;

    if(*l)
        t = (*l)->e,
        (*l)->e = t->p,
        (*l)->e->n = 0,
        d = t->d,
        free(t),
        (*l)->size--;

    if(!(*l)->e) free(*l);

    return d;
}

```
> 0 votes

# Answer
# JavaScript, 188

```
function L(){N=null;E=[N,N];t=this;h=E;t.u=i=>h=[i,h];
t.o=_=>h==E?N:h[+!(h=h[1])];t.e=(i,l)=>h=(l||h)==E?[i,
E]:[(l||h)[0],t.e(i,(l||h)[1])];t.s=_=>{o="";while(i=t.o())
{o+=i+","}return o}}

```

(Line breaks added for readability, not needed for answer or counted as bytes)

## Usage

### Methods

* `u(item)`: P**u**sh
* `o() -> item`: P**o**p (or dequeue)
* `e(item)`: **E**nqueue
* `s() -> string`: Convert to a **s**tring

### Example

```
let failed = _ => { throw Error(); };
let list = new L();

// Stack
list.u(1);
list.u(3);

list.o() === 3 || failed();
list.u(2);
list.o() === 2 || failed();
list.o() === 1 || failed();
list.o() === null || failed();

// Queue

list.e(1);
list.e(2);

list.o() === 1 || failed();
list.e(3);
list.o() === 2 || failed();
list.o() === 3 || failed();
list.o() === null || failed();

// Reverse
list.u(1);
list.u(2);
list.u(3);

list.s() === "3,2,1," || failed();

```

## Explanation

```
function L(){
    N=null; // end marker
    // a node has the format [item, rest]
    E=[N,N]; // end marker, is a node
    t=this;
    h=E; // head of list, is a node

    t.d = _ => JSON.stringify(h);

    t.u=i=>h=[i,h]; // push

    t.o=_=> // pop/deque
        h==E?
        N:
        h[+!(h=h[1])]; // set head to rest, return item (index into zeroth index by casting an assignment to a value to a bool to a float)

    // t.e acts recursively, we use `||` to set a default for when the user calls
    t.e=(i,l)=> // enqueue (user caller leaves `l` undefined)
        h=
            (l||h)==E?
                [i, E]: // if at end, insert new item right before
                [(l||h)[0],t.e(i,(l||h)[1])]; // else keep current value and process rest recursively

    t.s=_=>{
        o="";
        while(i=t.o()) {
            o+=i+","
        }
        return o
    }
}

```

## Notes

List can't store anything JavaScript casts to `false` (`null`, `false`, `0`, `[]`, etc.). Repeated pop operations on an empty list have no effect. Ignore the return values of push and enqueue. Because I use global variables to reduce character count, only one list can be created.
> 0 votes

---
Tags: code-golf, stack, data-structures
---


title: Next Shared Totient

text:
# Question
Title: Next Shared Totient
The totient function \\$\phi(n)\\$, also called Euler's totient function, is defined as the number of positive integers \\$\le n\\$ that are relatively prime to (i.e., do not contain any factor in common with) \\$n\\$, where \\$1\\$ is counted as being relatively prime to all numbers. (from WolframMathworld)

## Challenge

Given an integer \\$N \> 1\\$, output the lowest integer \\$M \> N\\$, where \\$\phi(N) = \phi(M)\\$. If \\$M\\$ does not exist, output a non-ambiguous non-positive-integer value to indicate that M does not exist (e.g. 0, -1, some string).

Note that \\$\phi(n) \geq \sqrt n\\$ for all \\$n \> 6\\$

## Examples

```
Where M exists
 15 -> 16  (8)
 61 -> 77  (60)
 465 -> 482 (240)
 945 -> 962 (432)

No M exists
 12  (4)
 42 (12)
 62 (30)

```

Standard loopholes apply, shortest answer in bytes wins.

Related

# Answer
# JavaScript (ES6),  ~~83 ... 76~~  74 bytes

Returns `true` if \\$M\\$ does not exist.

Derived from this answer by xnor.

```
f=(n,q,P=(n,d=n)=>p=--d&&P(n,d)+1-P(n%d?1:d))=>P(n)^q?p>q*q||f(n+1,q||p):n

```

Try it online!

## How?

### Computing \\$\phi(n)\\$

This is based on the formula:

$$\sum\_{d|n}\phi(d)=n$$

which implies:

$$\phi(n)=n-\sum\_{d|n,d\<n}\phi(d)$$

But in the JS implementation, we actually compute:

$$\begin{align}P(n)&=\sum\_{d=1}^{n-1}1-\delta\_{d|n}P(d)\\ &=n-1-\sum\_{d|n,d\<n}P(d)\end{align}$$

It leads to the same results, except \\$P(1)=0\\$ instead of \\$\phi(1)=1\\$. This is fine because we don't need to support \\$n=1\\$, as per the challenge rules. And this allows us to do the following recursive call:

```
P(n % d ? 1 : d)

```

which evaluates to \\$0\\$ if \\$d\\$ is not a divisor of \\$n\\$.

### Wrapper code

At each iteration, we compute \\$p=P(n)\\$. The result of the first iteration is saved into \\$q\\$. We then increment \\$n\\$ until \\$p=q\\$ (success) or \\$p\>q^2\\$ (failure).
> 10 votes

# Answer
# Jelly,  ~~11~~  10 bytes

```
r²ÆṪẹḢ$+⁸Ḣ

```

A monadic Link accepting a positive integer which yields a non-negative integer (`0` if no \\$M\\$ exists).

**Try it online!**

### How?

```
r²ÆṪẹḢ$+⁸Ḣ - Link: integer, n
 ²         - (n) squared
r          - (n) inclusive range (n²)
  ÆṪ       - Euler totient (vectorises)
      $    - last two links as a monad:
     Ḣ     -   head    - i.e. yield totient(n)
                           and leave [totient(n+1),...,totient(n²)]
    ẹ      -   indices of (i.e. a list of offsets to higher Ms)
        ⁸  - chain's left argument (n)
       +   - add (vectorises) (i.e. a list of higher Ms)
         Ḣ - head (note head-ing an empty list yields zero)

```
> 8 votes

# Answer
# Perl 6, ~~57~~ 52 bytes

*-5 bytes using the `.&` operator thanks to Jo King*

```
{first *.&($!={grep 1,($_ Xgcd^$_)})==.$!,$_^..$_²}

```

Try it online!

Returns `Nil` if no solution was found.

### Explanation

```
{                                                 }  # Anonymous block
                       $_ Xgcd^$_     # gcds of m and 0..m-1
               grep 1,                # Filter 1s
              {                   }   # Totient function
          ($!=                     )  # Assign to $!
 first                                   ,$_^..$_²  # First item of n+1..n² where
       *.&                          ==.$!           # ϕ(m) == ϕ(n)

```
> 7 votes

# Answer
# Jelly, ~~13~~ 12 bytes

```
r²ÆṪ=€Ḣ$T+⁸Ḣ

```

Try it online!

A monadic link taking an integer and returning the next integer with shared totient or zero.

## Explanation

### Main link (takes integer argument z)

```
r²           | Range from z to z ** 2 inclusive
  ÆṪ         | Totient function of each
       $     | Following as a monad
    =€Ḣ      | - Check whether each equal to the first, popping the first before doing so
        T    | Truthy indices
         +⁸  | Plus z
           Ḣ | - Head (returns 0 if the previous link yielded an empty list)

```
> 5 votes

# Answer
# 05AB1E, ~~11~~ ~~10~~ ~~9~~ 7 bytes

```
L+.Δ‚ÕË

```

-1 byte with help from *@ExpiredData*.
-2 bytes thanks to *@Grimmy*.

Outputs `-1` if no \\$m\\$ exists.

Try it online or verify all test cases.

**Explanation:**

```
L        # Push a list in the range [1, (implicit) input-integer n]
 +       # Add the (implicit) input-integer n to each to make the range [n+1, 2n]
  .Δ     # Get the first value of this list which is truthy for
         # (or results in -1 if none are truthy):
    ‚    #  Pair the current value with the (implicit) input-integer n
     Õ   #  Get the Euler's totient of both
      Ë  #  Check whether both are equal to each other
         # (after which the result is output implicitly)

```

Most answers use \\$n^2\\$ as the range to check in, but this answer uses \\$2n\\$ instead to save a byte. If we look at the Mathematica implementation on the oeis sequence A066659 we can see it also uses the range \\$\[n+1, 2n+1)\\$ to check in.
> 5 votes

# Answer
# Gaia, 11 bytes

```
:sUt¦ṇ=∆:+¿

```

Try it online!

```
:s		| push n,n^2
  U		| push range [n, n + 1, ..., n^2]
   t¦		| calculate [phi(n),phi(n+1), ..., phi(n^2)]
     ṇ		| push [phi(n+1), phi(n+2), ..., phi(n^2)], phi(n)
      =∆	| find 1-based index of first in the list equal to phi(n), returning 0 if none
	:	| dup the index
	 +¿	| if the index is falsey, do nothing (leaving 0 on the stack)
		| otherwise add (implicitly) n
		| and implicitly print top of stack

```
> 4 votes

# Answer
# Python 2, 115 bytes

```
lambda N:next((j for j in range(N+1,max(6,t(N)**2))if t(j)==t(N)),0)
t=lambda n:sum(k/n*k%n>n-2for k in range(n*n))

```

Try it online!

Returns `0` for falsey. The totient function `t` is based on Dennis's answer to a previous question.

Times out on TIO for `N=62`.
> 3 votes

# Answer
# Ruby, ~~70~~ 68 bytes

```
->n{(n+1..n*n).find{|m|g=->g{(1..g).sum{|h|1/h.gcd(g)}};g[m]==g[n]}}

```

Try it online!

Returns `nil` if not found.
> 2 votes

# Answer
# Python 3, ~~160~~ 121 bytes

Saved 39 bytes thanks to @JoKing!

Returns `None` if no \\$M\\$ exists:

```
import math
t=lambda n:sum(math.gcd(i,n)<2for i in range(n))
def s(x):
 n=x
 while n<x*x:
  n+=1
  if t(n)==t(x):return n

```

Try it online!

If throwing an exception is allowed when no \\$M\\$ exists:

# Python 3, ~~145~~ 114 bytes

Saved 31 bytes thanks to @JoKing!

```
lambda n:[t(i+1)for i in range(n,n*n)].index(t(n))-~n
import math
t=lambda n:sum(math.gcd(i,n)<2for i in range(n))

```

Try it online!
> 1 votes

# Answer
# Python 3, 97 bytes

```
lambda x,n=1:[n>x*x,x+n][t(x+n)==t(x)]or s(x,n+1)
t=lambda n:sum(k//n*k%n>n-2for k in range(n*n))

```

Try it online!

Totient function taken from Chas Brown's answer, originally from Dennis.Returns `True` for cases where `M` doesn't exist, though if that doesn't satisfy you, a far less efficient version that returns `False` is only two bytes longer.
> 1 votes

# Answer
# , ~~42~~ 31 bytes

```
(1{]) ::0[([+[:I.{=}.)5 p:i.@*:

```

Try it online!

Returns `0` if no \\$M\\$ exists.

## Explanation :

(of the previous version)

The argument is `n`

```
                              @*:   find n^2 and
                            i.      make a list 0..n^2-1
                           +        to each number in the list add
                          ]         the argument (n) -> list n..n^2+n-1
                      5 p:          find the totient of each number in the above list
                    @(           )  use the above result as an argument for
          (        )                the next verb
                =                   compare
                 {.                 the head of the list
               ]                    with each number in the list
           [:I.                     get the indices where the above is true
 (    ) ::0                         try the verb in parentheses and return 0 if it failed
   1{]                              get the second (0-based indexing) element
  +                                 and add n to it

```
> 0 votes

# Answer
# Japt, ~~21~~ 19 bytes

```
ôU ÅæÈo èjX ¥Uo èjU

```

Try it

```
ôU                      range [input ...input + input]
   Å                    cut off first element
      æÈ                return the first element to return a truty value when passed to:
        o               range [0... next element]
          è             number of elements that are..
           jX           coprime to next element.
              ¥         equal to
               Uo èjU   num of coprimes of input

```

Outputs `null` if no \\$m\\$ exists.

Thanks to @Shaggy for reminding me of ô() which gives the range needed
> 0 votes

---
Tags: code-golf, number-theory
---