title: Draw 'Til You Drop

text:
# Question
Title: Draw 'Til You Drop
In Dungeons & Dragons 5th edition (as well as most other editions), there exists a magic item called the *Deck of Many Things*. It is an incredibly powerful item, as the cards all have very strong positive or negative effects. To use the deck, a character declares a number, and then draws up to that number of cards, with the effects applying in sequence. If the character does not draw all of the cards that they declared, and it has been at least 1 hour since the last card has been drawn, the rest of the cards are automatically drawn for them and the effects applied. After each card is drawn, it is returned to the deck, and the deck is shuffled.

The following is a list of the effects of drawing each of the cards1:

* **Balance**: Your mind suffers a wrenching alteration, causing your alignment to change. Lawful becomes chaotic, good becomes evil, and vice versa. If you are true neutral or unaligned, this card has no effect on you.
* **Comet**: If you single-handedly defeat the next hostile monster or group of monsters you encounter, you gain experience points enough to gain one level. Otherwise, this card has no effect.
* **Donjon**: You disappear and become entombed in a state of suspended animation in an extradimensional sphere. Everything you were wearing and carrying stays behind in the space you occupied when you disappeared. You remain imprisoned until you are found and removed from the sphere. You can’t be located by any divination magic, but a wish spell can reveal the location of your prison. You draw no more cards.
* **Euryale**. The card’s medusa-like visage curses you. You take a -2 penalty on saving throws while cursed in this way. Only a god or the magic of The Fates card can end this curse.
* **The Fates**: Reality’s fabric unravels and spins anew, allowing you to avoid or erase one event as if it never happened. You can use the card’s magic as soon as you draw the card or at any other time before you die.
* **Flames**: A powerful devil becomes your enemy. The devil seeks your ruin and plagues your life, savoring your suffering before attempting to slay you. This enmity lasts until either you or the devil dies.
* **Fool**: You lose 10,000 XP, discard this card, and draw from the deck again, counting both draws as one of your declared draws. If losing that much XP would cause you to lose a level, you instead lose an amount that leaves you with just enough XP to keep your level.
* **Gem**: Twenty-five pieces of jewelry worth 2,000 gp each or fifty gems worth 1,000 gp each appear at your feet.
* **Idiot**: Permanently reduce your Intelligence by 1d4 + 1 (to a minimum score of 1). You can draw one additional card beyond your declared draws.
* **Jester**: You gain 10,000 XP, or you can draw two additional cards beyond your declared draws. Discard this card after drawing it.
* **Key**: A rare or rarer magic weapon with which you are proficient appears in your hands. The GM chooses the weapon.
* **Knight**: You gain the service of a 4th-level fighter who appears in a space you choose within 30 feet of you. The fighter is of the same race as you and serves you loyally until death, believing the fates have drawn him or her to you. You control this character.
* **Moon**: You are granted the ability to cast the wish spell 1d3 times.
* **Rogue**: A nonplayer character of the GM’s choice becomes hostile toward you. The identity of your new enemy isn’t known until the NPC or someone else reveals it. Nothing less than a wish spell or divine intervention can end the NPC’s hostility toward you.
* **Ruin**: All forms of wealth that you carry or own, other than magic items, are lost to you. Portable property vanishes. Businesses, buildings, and land you own are lost in a way that alters reality the least. Any documentation that proves you should own something lost to this card also disappears.
* **Skull**. You summon an avatar of death - a ghostly humanoid skeleton clad in a tattered black robe and carrying a spectral scythe. It appears in a space of the GM’s choice within 10 feet of you and attacks you, warning all others that you must win the battle alone. The avatar fights until you die or it drops to 0 hit points, whereupon it disappears. If anyone tries to help you, the helper summons its own avatar of death. A creature slain by an avatar of death can’t be restored to life.
* **Star**: Increase one of your ability scores by 2. The score can exceed 20 but can’t exceed 24.
* **Sun**: You gain 50,000 XP, and a wondrous item (which the GM determines randomly) appears in your hands.
* **Talons**: Every magic item you wear or carry disintegrates. Artifacts in your possession aren’t destroyed but do vanish.
* **Throne**: You gain proficiency in the Persuasion skill, and you double your proficiency bonus on checks made with that skill. In addition, you gain rightful ownership of a small keep somewhere in the world. However, the keep is currently in the hands of monsters, which you must clear out before you can claim the keep as yours.
* **Vizier**: At any time you choose within one year of drawing this card, you can ask a question in meditation and mentally receive a truthful answer to that question. Besides information, the answer helps you solve a puzzling problem or other dilemma. In other words, the knowledge comes with wisdom on how to apply it.
* **The Void**: This black card spells disaster. Your soul is drawn from your body and contained in an object in a place of the GM’s choice. One or more powerful beings guard the place. While your soul is trapped in this way, your body is incapacitated. A wish spell can’t restore your soul, but the spell reveals the location of the object that holds it. You draw no more cards.

(card descriptions copied from the D&D 5th edition SRD)

Some especially foolish players will draw a large number of cards at once, hoping to get at least one powerful boon to balance out the detrimental cards. As one might expect, this often results in the character's death or inability to continue to draw cards.

## The Challenge

Simulate repeated drawing from a 22-card *Deck of Many Things*, outputting each card drawn, stopping only when one of the following conditions is met:

* The character dies (via drawing **Skull**, or drawing 5 cards after drawing **Flames** or **Rogue**, without the benefit of **The Fates** or **Moon** active2).
* The character is incapable of drawing more cards (via the effects of **Donjon**, **Talons**, **The Void**3, or the character's Intelligence score dropping to 3 or lower via **Idiot**4).

## Rules

* The character's alignment, level, XP, and possessions other than the deck do not matter.
* The character's Intelligence score starts at 10.
* There is no maximum limit to the character's Intelligence or their stockpiled uses of *wish*.
* Uses of **The Fates** do not stack.
* The *wish* spell has a 1-in-3 chance of causing the character to never be able to use the *wish* spell again, in addition to its regular effect. If this occurs, the character can no longer use the spell to negate **Flames**, **Rogue**, or **Skull** \- the power of **The Fates** is their only recourse.
* The character always makes the following choices:
    + **The Fates** and **Moon** are solely used to get the character out of trouble from **Skull**, **Flames**, and **Rogue**. The character will never use them to reverse the effect of **Talons** or the *wish* spell being unable to be cast again, and cannot use them to reverse the effects of **Donjon** and **The Void**. The character will immediately use one *wish* spell to negate the effects of **Skull**, **Flames**, or **Rogue** upon drawing one of them, and it will always succeed. The character will always use **The Fates** before using *wish*.
    + The character always chooses to draw more cards with the effects of **Idiot** and **Jester** (appropriately).
    + The effect of **Star** is always used to increase Intelligence by 2, to avoid having to stop drawing cards via the effect of **Idiot**.
* The NPC ally summoned by **Knight** is not powerful enough to save the character from their untimely demise.
* Any increases or decreases to Intelligence (via **Star** or **Idiot**, respectively) must be reflected in the output (either by noting the change (`+2` or `-(1d4+1)`), or by outputting the current Intelligence score after the effect takes place).
* Any changes to the number of *wish* uses the character has stockpiled must similarly be reflected in the output, including a *wish* causing the character to not be able to use *wish* anymore.
* All random selections are from uniform discrete distributions.
* You may choose any set of 22 distinct outputs to output for the cards drawn - the cards' names do not have to be used.
* You may output changes in Intelligence, *wish* uses, and *wish* becoming unusable in any consistent, unambiguous manner of your choosing.
* The character may use *wish* or the power of **The Fates** to avoid death if the appropriate card is drawn as the fifth card after drawing **Rogue** or **Flames**. Only if *wish* is unusable or all of the uses have been used, as well as **The Fates** is not drawn in time or has already been used, will the character die.
* **Fool** and **Jester** are discarded after they are drawn. All other cards are immediately returned to the deck, and the deck is then shuffled.
* If there are multiple stacks of **Rogue** and/or **Flame** active, only one use of **The Fates** or *wish* is necessary to dispel all of them.
* Drawing multiple cards at once via **Jester** or **Fool** does not advance the turn counter on **Flames** and/or **Rogue**.

## Examples

Each line represents a sequence of draws. Changes to Intelligence and *wish* uses are shown by the current value in parentheses. A `C` next to a *wish* use denotes that *wish* cannot be used anymore. A `F` denotes that the power of **The Fates** was used to avoid death. Additional comments are provided for explanatory purposes, in the form of Python-style comments.

```
Void # Can't draw with your soul ripped out of your body.
Throne, Euryale, Rogue, Star (12), Donjon # Can't draw while in suspended animation.
Moon (3), Throne, Sun, Flames (2), Fool, Idiot (6), Flames (1 C), The Fates, Skull (F), Skull # Two uses of wish were used on the two Flames draws. The second use rendered the character unable to use wish again. The Fates was used on the first Skull. When the second Skull came up, there was no way for the character to save himself, so he died.
Idiot (5), Star (7), Idiot (3) # Too dumb to draw.
Sun, Star (12), Talons # Talons destroys the deck.
Fates, Throne, Moon (2), Fates, Skull (F), Skull # Fates doesn't stack
Fates, Flames, Euryale, Fates, Skull, Void
Flames, Comet, Euryale, Gem, Knight, Key # 5 draws after Flames, the hero dies
Rogue, Balance, Throne, Gem, Idiot (8), Vizier, Sun # 5 draws plus one extra from Idiot

```

## Reference Implementation

```
#!/usr/bin/env python3

import random

deck="""Sun
Moon
Star
Throne
Key
Knight
Void
Flames
Skull
Ruin
Euryale
Rogue
Jester
Vizier
Comet
Fates
Gem
Talons
Idiot
Donjon
Balance
Fool""".split()

random.shuffle(deck)

int_stat = 10
wish_uses = 0
wish_expired = False
fates = False
turn_count = None

while True:
    card = deck.pop()
    if card == "Fates":
        if turn_count is None:
            fates = True
            print(card)
        else:
            turn_count = None
            fates = False
            print("{} (F)".format(card))
    elif card == "Moon":
        wish_uses += random.randint(1, 3)
        if turn_count is None:
            print("{} ({})".format(card, wish_uses))
        else:
            turn_count = None
            wish_uses -= 1
            print("{} ({}) ({})".format(card, wish_uses+1, wish_uses))
    elif card in ["Flames", "Rogue"]:
        if turn_count is None:
            turn_count = 5
        if fates:
            fates = False
            turn_count = None
            print("{} (F)".format(card))
        elif wish_uses > 0 and not wish_expired:
            wish_uses -= 1
            turn_count = None
            wish_now_expired = random.choice([False, False, True])
            print("{} ({}{})".format(card, wish_uses, " C" if wish_expired else ""))
            wish_expired = wish_now_expired
        else:
            print("{}".format(card))
    elif card == "Idiot":
        int_stat -= random.randint(2, 5)
        print("{} ({})".format(card, int_stat))
        if turn_count is not None:
          turn_count += 1
        if int_stat <= 3:
            break
    elif card == "Star":
        int_stat += 2
        print("{} ({})".format(card, int_stat))
    elif card == "Skull":
        if fates:
            fates = False
            turn_count = None
            print("{} (F)".format(card))
        elif wish_uses > 0 and not wish_expired:
            wish_uses -= 1
            turn_count = None
            wish_now_expired = random.choice([False, False, True])
            print("{} ({}{})".format(card, wish_uses, " C" if wish_expired else ""))
            wish_expired = wish_now_expired
        else:
            print(card)
            break
    elif card in ["Donjon", "Void", "Talons"]:
        print(card)
        break
    elif card == "Fool":
        print(card)
        if turn_count is not None:
            turn_count += 1
    elif card == "Jester":
        print(card)
        if turn_count is not None:
            turn_count += 2
    else:
        print(card)
    if card not in ["Fool", "Jester"]:
        deck.append(card)
        random.shuffle(deck)
    if turn_count is not None:
        turn_count -= 1
    if turn_count == 0:
        break

```

---

\[1\]: Technically, there are two variants: one with 13 cards, and one with 22 cards. We're only concerned about the full 22-card version here.

\[2\]: **Flame** and **Rogue** don't normally outright kill the character, but the hostile NPC is assumed to have found and killed the foolish character after they have time to draw 5 more cards. The spectre summoned by **Skull** is extremely difficult to fight, and it's assumed that the character doesn't win. Only divine/magical intervention via **The Fates** or **Moon** can save the foolish character from their death by these 3 cards.

\[3\]: We assume the character's friends are smart enough to not try to rescue the character and allow them to draw more cards.

\[4\]: An Intelligence score of 3 is roughly equivalent to a wild animal, which wouldn't be able to actively make the choice to draw cards.

# Answer
# JavaScript (ES6), 379 bytes

```
for(D=[...Array(21)].map((a,b)=>b),d={},i=10,w=e=f=t=0,F=_=>f=t=o=0,W=_=>{w--,t=0,o=w+(e?' C':''),e=1>r(2)},r=a=>0|Math.random()*a,$=1;$;){for(;d[c=r(22)];);o='',c?3>c?(t&&(t+=c),d[c]=1):4>c?f?F():0<w&&!e?W():$=0:7>c?$=0:9>c?(!t&&(t=5),f?F():0<w&&!e&&W()):10>c?(w+=1+r(2),t?(t=0,o=[w,--w]):o=w):11>c?(i-=2+r(3),o=i,$=3<i):12>c&&(i+=2,o=i):t?F():f=1,console.log(c,o),t&&(t--,$=t)}
```

### Ungolfed

```
let

print = (...x) => console.log(card, ...x),

// Uncomment for more human-friendly output:
// print = (...x) => console.log(`Fates Fool Jester Skull Donjon Void Talons Flames Rogue Moon Idiot Star Sun Throne Key Knight Ruin Euryale Vizier Comet Gem Balance`.split` `[card] + x.map(x => ` (${x})`).join``),

deck = [...Array(21)].map((_,i)=>i),
discard = {},

intelligence = 10,
wishUses = 0,
wishExpired = false,
fates = false,
turns = 0,

useFates = () => {
    fates = false
    turns = 0
    print('F')
},
useWish = () => {
    wishUses--
    turns = 0
    print(wishUses + (wishExpired ? ' C' : ''))
    wishExpired = random(2) < 1
},

random = n => Math.random() * n | 0,

canDraw = true

while(canDraw){
 // card = deck.splice(random(deck.length), 1)[0]
    while(discard[card = random(22)]);

    if(card){
        if(card < 3){
            // 1: Fool
            // 2: Jester
            if(turns){
                turns += card
            }
   print()
   discard[card] = 1
        }else if(card < 4){
            // 3: Skull
            if(fates){
                useFates()
            }else if(wishUses > 0 && !wishExpired){
                useWish()
            }else{
                print()
                canDraw = false
            }
        }else if(card < 7){
            // 4: Donjon
            // 5: Void
            // 6: Talons
            print()
            canDraw = false
        }else if(card < 9){
            // 7: Flames
            // 8: Rogue
            if(!turns){
                turns = 5
            }
            if(fates){
                useFates()
            }else if(wishUses > 0 && !wishExpired){
                useWish()
            }else{
                print()
            }
        }else if(card < 10){
            // 9: Moon
            wishUses += 1 + random(2)
            if(!turns){
                print(wishUses)
            }else{
                turns = 0
                wishUses--
                print(wishUses + 1, wishUses)
            }
        }else if(card < 11){
            // 10: Idiot
            intelligence -= 2 + random(3)
            print(intelligence)
            if(intelligence <= 3){
                canDraw = false
            }
        }else if(card < 12){
            // 11: Star
            intelligence += 2
            print(intelligence)
        }else{
            print()
        }
    }else{
        // 0: Fates
        if(!turns){
            fates = true
            print()
        }else{
            useFates()
        }
    }

    if(turns){
        turns--
        if(!turns){
            canDraw = false
        }
    }
}
```

### Explanation of Output

Cards range from 0-21 as follows:

* 0: Fates
* 1: Fool
* 2: Jester
* 3: Skull
* 4: Donjon
* 5: Void
* 6: Talons
* 7: Flames
* 8: Rogue
* 9: Moon
* 10: Idiot
* 11: Star
* 12 though 21: Sun, Throne, Key, Knight, Ruin, Euryale, Vizier, Comet, Gem, Balance

A reversal of Skull, Flames, or Rogue via The Fates is denoted with a `0`.

---

# JavaScript (ES6), 792 bytes

Previous version using card names, before I found out that any 22 distinct outputs are allowed.

```
d=`Sun Moon Star Throne Key Knight Void Flames Skull Ruin Euryale Rogue Jester Vizier Comet Fates Gem Talons Idiot Donjon Balance Fool`.split` `,i=10,w=0,W=!1,f=!1,t=null,F=()=>{f=!1,t=null,_('F')},U=()=>{w--,t=null,_(w+(W?' C':'')),W=1>r(2)},_=(...a)=>console.log(c+a.map(b=>` (${b})`).join``),r=a=>0|Math.random()*a,$=!0;for(;$;)c=d.splice(r(d.length),1)[0],'Fates'==c?null==t?(f=!0,_()):F():'Moon'==c?(w+=1+r(2),null==t?_(w):(t=null,w--,_(w+1,w))):'Idiot'==c?(i-=2+r(3),_(i),3>=i&&($=!1)):'Star'==c?(i+=2,_(i)):'Flames'==c||'Rogue'==c?(null==t&&(t=5),f?F():0<w&&!W?U():_()):'Skull'==c?f?F():0<w&&!W?U():(_(),$=!1):'Donjon'==c||'Void'==c||'Talons'==c?(_(),$=!1):'Fool'==c?null!==t&&(t+=1):'Jester'==c?null!==t&&(t+=2):_(),['Fool','Jester'].includes(c)||d.push(c),null!==t&&t--,0===t&&($=!1)
```

### Ungolfed

```
let

deck = `Sun Moon Star Throne Key Knight Void Flames Skull Ruin Euryale Rogue Jester Vizier Comet Fates Gem Talons Idiot Donjon Balance Fool`.split` `,

intelligence = 10,
wishUses = 0,
wishExpired = false,
fates = false,
turns = null,

useFates = () => {
    fates = false
    turns = null
    print('F')
},
useWish = () => {
    wishUses--
    turns = null
    print(wishUses + (wishExpired ? ' C' : ''))
    wishExpired = random(2) < 1
},

print = (...x) => console.log(card + x.map(x => ` (${x})`).join``),
random = n => Math.random() * n | 0,

canDraw = true

while(canDraw){
    card = deck.splice(random(deck.length), 1)[0]

    switch(card){
    case 'Fates':
        if(turns === null){
            fates = true
            print()
        }else{
            useFates()
        }
        break
    case 'Moon':
        wishUses += 1 + random(2)
        if(turns === null){
            print(wishUses)
        }else{
            turns = null
            wishUses--
            print(wishUses + 1, wishUses)
        }
        break
    case 'Idiot':
        intelligence -= 2 + random(3)
        print(intelligence)
        if(intelligence <= 3){
            canDraw = false
        }
        break
    case 'Star':
        intelligence += 2
        print(intelligence)
        break
   case 'Flames':
   case 'Rogue':
        // Changed Condition
        if(turns === null){
            turns = 5
        }

        if(fates){
            useFates()
        }else if(wishUses > 0 && !wishExpired){
            useWish()
        }else{
            // Added
            print()
        }
        break
    case 'Skull':
        if(fates){
            useFates()
        }else if(wishUses > 0 && !wishExpired){
            useWish()
        }else{
            print()
            canDraw = false
        }
        break
    case 'Donjon':
    case 'Void':
    case 'Talons':
        print()
        canDraw = false
        break
    case 'Fool':
        if(turns !== null){
            turns += 1
        }
        break
    case 'Jester':
        if(turns !== null){
            turns += 2
        }
        break
    default:
        print()
    }

    if(!['Fool', 'Jester'].includes(card)){
        deck.push(card)
    }

    if(turns !== null){
        turns--
    }

    if(turns === 0){
        canDraw = false
    }
}
```
> 4 votes

# Answer
# Java 10, ~~481~~ ~~480~~ ~~476~~ ~~470~~ ~~453~~ ~~439~~ ~~437~~ 436 bytes

```
v->{var r="";Math M=null;int i=10,d=22,c,F=0,t=0,w=0,W=0,j=2;for(j*=M.random();;){c=d;c*=M.random();r+=" "+c;t=c<1?(r+=t<(F=1)?"":"F"+(F=0))==""?-1:-1:c<2?0*(w+=M.random()*3-(t>0?0:1)):c<4?F>0?-1:t<1?6:t:c<5?F*w*W>(F=0)?-1:1:c>19?t+(t>0*d--*j++?j%2+1:0):t;W=c>1&c<5&w*W>0?(int)(M.random()*3)%2+0*w--:W;i-=c==5?M.random()*3+2:c==6?-2:0;r+=c>1&c<5&F>0?"F"+(F=0):c>0&c<5?"w"+w+"W"+W:c>4&c<7?"i"+i:"";if(--t==0|c==5&i<4|c>6&c<10)return r;}}

```

Ported the Python3 reference implementation in Java, and then golfed it down.

-46 bytes thanks to *@ceilingcat*.

**Card outputs:**

> `0`: Fates
> `1`: Moon
> `2`: Flames
> `3`: Rogue
> `4`: Skull
> `5`: Idiot
> `6`: Star
> `7`/`8`/`9`: Donjon/Void/Talons
> `20`/`21`: Fool/Jester
>
> `10-19`: everything else (Sun/Throne/Key/Knight/Ruin/Euryale/Vizier/Comet/Gem/Balance)

Output format for wishes left, wishes used, intelligence left, and flag used:

```
4w1W0
4       // Card drawn
 w1     // New amount of wishes left
   W0   // Whether the wishes used flag is active (1) or inactive (0)

5i6
5       // Card drawn
 i6     // New intelligence

0F0
0       // Card drawn
 F0     // Fates used

```

**Explanation:**

Try it here or **Try it here with pretty-printed output**.

```
v->{                        // Method with empty unused parameter and String return-type
  var r="";                 //  Result-String, starting empty
  Math M=null;              //  Static Math to save bytes
  int i=10,                 //  Intelligence, starting at 10
      d=22,                 //  Amount of cards in the deck, starting at 22
      c,                    //  Current card drawn
      F=0,                  //  Fates flag, starting at inactive
      t=0,                  //  Turn-counter, starting at 0
      w=0,                  //  Wishes left, starting at 0
      W=0,                  //  Wishes used flag, starting at 0
      j=2;for(j*=M.random() //  Whether Jester/Fool is drawn first of the two, random 0/1
      ;;){                  //  Loop indefinitely:
    c=d;c*=M.random();      //   Draw a random 0-21 card (or less if Fool/Jester is gone)
    r+=" "+c;               //   Append the result with a space and this card
    t=c<1?                  //   If the card was Fates:
      (r+=t<(F=1)           //    Set the Fates-flag to active
                 ?          //    And if the turn-counter is 0:
        ""                  //     Append nothing
      :                     //    Else (the turn-counter is larger than 0):
       "F"+(F=0))           //     Append that Fates was used (and make Fates inactive)
      ==""?-1:-1            //    Then set the turn-counter to -1 (none)
    :c<2?                   //   If the card was Moon instead:
      0*(w+=M.random()*3    //    Increase the wishes by 0-2 randomly
         -(t>0?             //    Then, if the turn-counter is larger than 0
            0               //     Leave the (0-based random) wishes the same
           :                //    Else:
            1))             //     Subtract 1 from the (0-based random) wishes
      -1                    //    Set the turn-counter to -1 (none)
    :c<4?                   //   If the card was Flames or Rogue instead:
      F>0?                  //    If the Fates-flag is active:
       -1                   //     Set the turn-counter to -1 (none)
      :t<1?                 //    Else-if the turn-counter is 0 or -1 (none):
       6                    //     Set the turn-counter to 6
      :                     //    Else:
       t                    //     Leave the turn-counter the same
    :c<5?                   //   If the card was Skull instead:
        F                   //    If the Fates-flag is inactive
        *w                  //    or the amount of wishes is smaller than 1
        *W<1                //    or the wishes used flag is inactive
            +0*(F=0)?       //    (And set the Fates-flag to inactive)
         1                  //     Set the turn-counter to 1
        :                   //    Else:
         -1                 //     Set the turn-counter to -1 (none)
    :c>19?                  //   If the card was Fool or Jester instead:
      t+(t>0*d--            //    Remove the Fool/Jester from the Deck
            *j++            //    And increase `j` (Fool/Jester) by 1
                ?           //    If the turn-counter was not 0 or -1 (none):
          j%2+1             //     Increase either by 1 (Fool) or 2 (Jester)
         :                  //    Else:
          0)                //     Leave the turn-counter the same by increasing with 0
    :                       //   Else:
     t;                     //    Leave the turn-counter unchanged
    W=c>1&c<5               //   If the card drawn was Flames, Rogue or Skull,
      &w                    //   and the amount of wishes is at least 1,
        *W>0?               //   and the wishes used flag is active
       (int)(M.random()*3)%2//    Randomly set the wishes used flag to one of (0,0,1)
       +0*w--               //    And decrease the wishes left by 1
      :                     //   Else:
       W;                   //    Keep the wishes used flag the same
    i-=c==5?                //   If the card drawn was Idiot:
        M.random()*3+2      //    Decrease the intelligence by 2-5 randomly
       :c==6?               //   Else-if the card drawn was Star:
        -2                  //    Increase the intelligence by 2
       :                    //   Else:
        0;                  //    Leave the intelligence the same
    r+=c>1&c<5              //   If the card drawn was Flames, Rogue or Skull,
       &F>0?                //   and Fates is active
        "F"+(F=0)           //    Append that Fates was used (and make Fates inactive)
       :c>0&c<5?            //   Else-if the card drawn was Moon, Flames, Rogue or Skull:
        "w"+w+"W"+W         //    Append the amount of wishes left and wishes used flag
       :c>4&c<7?            //   Else-if the card drawn was Idiot or Star:
        "i"+i               //    Append the amount of intelligence left
       :                    //   Else:
        "";                 //    Append nothing
    if(--t                  //   Decrease the turn-counter by 1
          ==0               //   And if the turn-counter is now 0,
       |c==5                //   or the card drawn was Idiot,
             &i<4           //   and the intelligence dropped below 4,
       |c>6&c<10)           //   or the card drawn was Donjon, Void or Talons:
         return r;}}        //    Return the result of the game

```
> 2 votes

# Answer
# Kotlin, 1173 bytes

```
fun main(args:Array<String>){val d="Sun Moon Star Throne Key Knight Void Flames Skull Ruin Euryale Rogue Jester Vizier Comet Fates Gem Talons Idiot Donjon Balance Fool".split(" ");var c=(Math.random()*22).toInt();var i=10;var u=0;var e=false;var f=false;var t=1;r@while(true){when(c){15->{if(t>=1){f=true;println(c)}else{t = 1;f = false;println("${d[c]} (F)")}}1->{u+=(Math.random()*3).toInt()+1;if(t>=1){println("${d[c]} ($u)")}else{t=1;u-=1;println("${d[c]} (${u + 1}) ($u)")}}in arrayOf(7,11)->{if(t>=1){t=5};if(f){f=false;t=1;println("${d[c]} (F)")}else if(u>0&&!e){u-=1;t=1;val n=(Math.random()*3).toInt();println("${d[c]} ($u$e)");e=n==0}else{println(d[c])}}18->{i-=(Math.random()*4).toInt()+2;println("${d[c]} ($i)");if (t!=0){t+=1};if(i<=3){break@r}}2->{i+=2;println("${d[c]} ($i)")}8->{if(f){f=false;t=1;println("${d[c]} (F)")}else if(u>0&&!e){u-=1;t=1;val n=(Math.random()*3).toInt();println("${d[c]} ($u$e)");e=n==0}else{println(c);break@r}}in arrayOf(6,17,19)->{println(d[c]);break@r}21->{println(d[c]);if(t!=0){t += 1}}12->{println(d[c]);if(t!=0){t+=2}}else->{println(d[c])}};if((c !in arrayOf(12,21))){c=(Math.random()*23).toInt()};if(t!=0){t-=1}else{break}}}

```

It's runnable, too. - Try it online!

There's probably lots of bugs... let me know in the comments!
> 0 votes

---
Tags: code-golf, random, game
---


title: Help me cheat at Cheat

text:
# Question
Title: Help me cheat at Cheat
Cheat is a card game where you're trying to get rid of your hand. A turn looks something roughly like this:

1. Determine what card rank you have to play that turn. In most variants this is one rank higher than the previous turn.
2. Play 1-4 cards, face down. These don't have to match the valid rank. If they don't, it's considered a *cheat*. At this point any player may *challenge* you.
    * If nobody challenges you, play continues to the next player.
    * If somebody challenges you and you didn't cheat, they have to take all of the played cards.
    * If somebody challenges you and you did cheat, you have to take all of the played cards.

The strategy is mostly a mix of bluffing and card counting. I'm bad at math, though, so I'm going to cheat at Cheat and bring a bot with me.

# Input

The input will be, in any order or format you want:

1. The player's hand. If I know that they must have cards (for example, I've seen them pick them up), those will be listed in ascending order. Any unknowns will be listed afterwards as `?`. For example, if they have six cards and I know that two are 1's and one is a 4, a valid representation of the hand is `114???`. **?'s will always be listed after known cards.** `141???` and `11???4` are both invalid inputs and your code doesn't need to handle them.
2. The cards I definitely know are not part of their hand (I have them, I saw someone else pick them up, etc). The list will be in ascending order of rank. The list may be empty.
3. The cards the player claimed to play. If they claimed to play 3 7's, a possible input here would be `777`. The cards will always be the same rank.

The number of played cards will always be 1-4 and the ranks will always be 0-9. A rank will never appear more than four times in their hand + not their hand.

This is an example valid input:

```
33577??
01555688
55

```

This is an example invalid input:

```
35377?? # Out of order
7779    # Five 7's in total
23      # Two separate ranks played

```

# Output

A truthy value if we should **definitely** challenge. A falsey value if we might not want to challenge.

We always challenge if we know they cheated. We know they cheated if they played cards they couldn't possibly have:

```
12

3  # They don't have any 3's or ?'s
-------------
12?

33 # Fewer ?'s than played cards
-------------
123?
333
33 # Since we have three 3's they can't have two

```

The other time we challenge is if they play their last cards. Even if the play's legit it would end the game so we might as well challenge it.

```
1

1 # They'd win, so challenge anyway

```

# More Test Cases

**Truthy** (should challenge)

```
11445678?

22
-------------
????????
4
4444
-------------
12345678

9

```

**Falsey** (should not challenge)

```
1?
222
2
-------------
12?
22
22
-------------
?????

1111

```

# Scoring

Shortest code wins.

# Answer
# Pyth, 22 bytes

```
!}zS+*hzhS,/Q\?-4l@z+w

```

Try it online.
> 2 votes

# Answer
## JavaScript (ES6), 93 bytes

```
(h,s,c,g=(a,z=c[0])=>a.split(z).length-1)=>h.length==g(c)|g(h,'?')+g(h)<g(c)|g(h)+g(s)+g(c)>4

```

Accepts three strings of cards (characters `0`-`9` or `?`); returns `1` for challenge, `0` otherwise. Explanation:

```
(h,s,c,                 Input parameters
 g=(a,z=c[0])=>         Helper function defaults to claimed card
  a.split(z).length-1   Count cards matching (g(c) == c.length)
)=>h.length==g(c)       Does hand length equal claim length
  |g(h,'?')+g(h)<g(c)   Could hand not contain claimed cards
  |g(h)+g(s)+g(c)>4     Are there too many claimed cards

```
> 1 votes

# Answer
# C#6, 134 bytes

```
using System.Linq;
bool f(string a,string b,string c)=>a.Length==1|a.Count(x=>x==c[0]|x=='?')<c.Length|b.Count(x=>x==c[0])+c.Length>4;

```

(Note: In line with OP's example, this answer returns false even if opponent has more than one card and is playing all of his hand. In terms of strategy this should return true.)

Explanation:

`a`: Player's hand
`b`: Cards I definitely know...
`c`: Cards claimed to play

Ungolfed:

```
bool f(string a, string b, string c) =>
    a.Length == 1                               // Last card played
    | a.Count(x => x == c[0] | x == '?' )       // Count no. of cards that surely/may match claimed cards
                                                // Assuming all claimed cards are the same, just compare with c[0]
        < c.Length                              // I'm sure you don't have that many cards...
    | b.Count(x => x == c[0]) + c.Length > 4;   // ... Or that there can't be that many cards in play

```
> 1 votes

# Answer
# Java 8, ~~169~~ 135 bytes

```
(a,b,c)->{int C=c.length();char x=c.charAt(0);return a.length()==C|(a+0).split(x+"|\\?",-1).length<=C|5-(b+0).split(""+x,-1).length<C;}

```

**Explanation:**

Try it here.

```
(a,b,c)->{            // Method with three String parameters and boolean return-type
  int C=c.length();   //  The amount of cards played by your opponent this turn
  char x=c.charAt(0); //  The card played by your opponent this turn
  return a.length()==C//  Return true if your opponent played his entire hand (final round)
    |(a+0).split(x+"|\\?",-1).length
                      //   Or the amount of the played card and '?' in your opponent's hand
      <=C             //   is smaller than the amount of cards played
    |5-(b+0).split(""+x,-1).length
                      //   Or if 4 minus the amount of the played card are part of the
                      //   cards you definitely know,
     <C;              //   is smaller than the amount of cards played
}                     // End of method

```

NOTE: `(s+0).split("c",-1).length-1` gives the amount of times the character `c` occurs in String `s`. So the comments in the explanation above are correct, but the code might seem different because of it. The `(a+0).split(x+"|\\?",-1).length-1<C` is golfed to `(a+0).split(x+"|\\?",-1).length<=C` and the `4-(b+0).split(""+x,-1).length-1<C` is golfed to `5-(b+0).split(""+x,-1).length<C`.
> 1 votes

---
Tags: code-golf, card-games
---


title: Levenshtein distance & OEIS (Cops)

text:
# Question
Title: Levenshtein distance & OEIS (Cops)
This is the Cop post. The Robber post is here.

---

Your task is to take an integer input **N** and output the **Nth** digit in the sequence OEIS A002942.

The sequence consists of the square numbers written backwards:

```
1, 4, 9, 61, 52, 63, 94, 46, 18, 1, 121, 441, ...

```

Note that leading zeros are trimmed away (**100** becomes **1**, not **001**). Concatenating this into a string (or one long number gives):

```
1496152639446181121441

```

You shall output the **Nth** digit in this string/number. You may choose to take **N** as 0-indexed or 1-indexed (please state which one you choose).

### Test cases (1-indexed):

```
N = 1,      ==> 1
N = 5,      ==> 1
N = 17,     ==> 1   <- Important test case! It's not zero.
N = 20,     ==> 4
N = 78,     ==> 0
N = 100,    ==> 4

```

Your code should work for numbers up to **N = 2^15** (unless your language can't handles 32 bit integers by default, in which case **N** can be lower).

---

### Cops:

You must write two functions/programs, in the same language, that do the same thing. You have to post one of the functions/programs, as well as the Levenshtein distance between the two functions/programs you have written. The Levenshtein distance is measured in characters (so addition of a two byte character will give a LD = 1).

The unrevealed code can not be longer than the original solution (but it can be the same size). The robbers will attempt to write a code with the exact Levenshtein distance you gave (it can be different from your unrevealed code, as long as it works).

The winner will be the uncracked submission that has the lowest Levenshtein distance.

You may check the Levenshtein distance here!

---

If your submission goes uncracked for 7 days then you may reveal the alternative code you have written and mark your submission as safe.

---

# Answer
# Haskell, LD = 13, cracked

```
((snd.span(<'1').reverse.show.(^2)=<<[1..])!!)

```

Try it online!

I double-checked that leading zeros are trimmed ;)

**Explanation:**

```
                    [1..]     -- for each element in [1,2,3,4,5,...]
                 =<<          -- apply the following functions
             (^2)             -- square [1,4,9,16,25,...]
           show.              -- convert to string ["1","4","9","16","25",...]
       reverse.               -- reverse ["1","4","9","61","52",...,"001",...]
   span(<'1').                -- split into leading zeros and remainder [("","1"),("","4"),...,("00","1"),...]
  snd.                        -- only keep remainder ["1","4","9","61","52",...,"1",...]
                              -- and concatenate the result "1496152..."
((                       )!!) -- index into the sequence

```
> 6 votes

# Answer
# JavaScript (ES6), LD = 103 (cracked)

Using such a high Levenshtein distance is probably not the best strategy, but let's try it anyway.

```
n => { for(i = 0, str = ''; i <= n; i++) { str += +[...i * i + ''].reverse().join(''); } return str[n]; }

```

### Test cases

```
let f =

n => { for(i = 0, str = ''; i <= n; i++) { str += +[...i * i + ''].reverse().join(''); } return str[n]; }

console.log(f(5))      // 1
console.log(f(17))     // 1
console.log(f(20))     // 4
console.log(f(78))     // 0
console.log(f(100))    // 4
console.log(f(274164)) // 1
```

### Intended solution

```
$=>eval(atob`Wy4uLkFycmF5KCQrMSldLm1hcCgoXyxpKT0+K1suLi5pKmkrJyddLnJldmVyc2UoKS5qb2luYGApLmpvaW5gYFskXQ`)

```

Encoded part:

```
[...Array($+1)].map((_,i)=>+[...i*i+''].reverse().join``).join``[$]

```
> 3 votes

# Answer
# cQuents 0, LD = 1, Cracked

```
":\r$*$

```

Try it online!

I thought this didn't work for leading zeroes, but it actually does - the reverse function in cQuents is coded as `int(reversed(str(n)))`.

## Explanation

```
"         Concatenate sequence together, get nth term in the string instead of the sequence
 :        Mode: Sequence: given input n, output the nth term, 1-indexed
          Each term in the sequences equals:
  \r      reverse(
    $*$           the index * the index
                  or
    $$            the index * the index
                   ) (implicit)

```
> 3 votes

# Answer
# Python 2, 104 bytes, LD=21 Invalid AND Cracked

```
d=lambda y:y if'0'!=str(y)[-1]else d(y/10)
lambda n:''.join([str(d(x*x))[::-1]for x in range(1,n)])[n-1]

```

~~P.S. Is an unlimited amount of whitespace and commenting allowed? If so this will not be hard to crack.~~
> 3 votes

# Answer
# 6502 machine code (C64), LD = 1 (cracked)

```
00 C0 20 FD AE A0 00 99 5B 00 C8 20 73 00 90 F7 99 5B 00 A2 0B CA 88 30 09 B9
5B 00 29 0F 95 5B 10 F3 A9 00 95 5B CA 10 F9 A9 00 A0 03 99 69 00 88 10 FA A0
20 A2 76 18 B5 E6 90 02 09 10 4A 95 E6 E8 10 F4 A2 03 76 69 CA 10 FB 88 F0 11
A2 09 B5 5C C9 08 30 04 E9 03 95 5C CA 10 F3 30 D6 A2 03 B5 69 95 57 CA 10 F9
A9 01 85 FB A2 03 A9 00 95 FB CA D0 FB A2 03 B5 FB 95 22 95 26 CA 10 F7 A9 00
A2 03 95 69 CA 10 FB A0 20 A2 02 46 25 76 22 CA 10 FB 90 0C A2 7C 18 B5 AA 75
ED 95 ED E8 10 F7 A2 7D 06 26 36 AA E8 10 FB 88 10 DD A0 0B A9 00 99 5A 00 88
D0 FA A0 20 A2 09 B5 5C C9 05 30 04 69 02 95 5C CA 10 F3 06 69 A2 FD 36 6D E8
D0 FB A2 09 B5 5C 2A C9 10 29 0F 95 5C CA 10 F4 88 D0 D7 E0 0A F0 05 E8 B5 5B
F0 F7 09 30 99 5B 00 C8 E8 E0 0B F0 04 B5 5B 90 F1 88 B9 5B 00 C9 30 F0 F8 A2
7C 18 B5 DB E9 00 95 DB E8 10 F7 90 14 88 30 05 B9 5B 00 D0 EA A2 7C F6 7F D0
03 E8 10 F9 4C 73 C0 B9 5B 00 4C D2 FF

```

**Online demo**, usage: `sys49152,n` where `n` is the 0-indexed input.

---

For the last test case, you need a bit of patience, as this poor machine has to do millions of bit-shifts and additions to present you the result ;)

The language here is the machine code, so LD is measured in this format -- nevertheless, to give something to start with, here's the program in `ca65` assembler source:

```
NUMSIZE         = 4     ; 32 bit integers ...
NUMSTRSIZE      = 11    ; need up to 11 characters for 0-terminated string

.segment "ZPUSR": zeropage
v_x:            .res    NUMSIZE         ; next number to be squared

.segment "ZPFAC": zeropage
v_n:            .res    NUMSIZE         ; input index (0-based), counts down
nc_string:      .res    NUMSTRSIZE      ; string buffer for numbers

.segment "ZPTMP": zeropage
mpm_arg1:       .res    NUMSIZE         ; arg1 for multiplication
mpm_arg2:       .res    NUMSIZE         ; arg2 for multiplication

.segment "ZPFAC2": zeropage
mpm_res:        .res    NUMSIZE         ; numeric result (mult and str convert)

; load address for creating a C64 .PRG file:

.segment "LDADDR"
                .word   $c000

.code

; first read number from command argument and convert to unsigned
; integer in little-endian:

                jsr     $aefd
                ldy     #$00
rn_loop:        sta     nc_string,y
                iny
                jsr     $73
                bcc     rn_loop
                sta     nc_string,y
                ldx     #NUMSTRSIZE
stn_copybcd:    dex
                dey
                bmi     stn_fillzero
                lda     nc_string,y
                and     #$f
                sta     nc_string,x
                bpl     stn_copybcd
stn_fillzero:   lda     #$0
                sta     nc_string,x
                dex
                bpl     stn_fillzero
                lda     #$0
                ldy     #(NUMSIZE-1)
stn_znumloop:   sta     mpm_res,y
                dey
                bpl     stn_znumloop
                ldy     #(NUMSIZE*8)
stn_loop:       ldx     #($81-NUMSTRSIZE)
                clc
stn_rorloop:    lda     nc_string+NUMSTRSIZE+$80,x
                bcc     stn_skipbit
                ora     #$10
stn_skipbit:    lsr     a
                sta     nc_string+NUMSTRSIZE+$80,x
                inx
                bpl     stn_rorloop
                ldx     #(NUMSIZE-1)
stn_ror:        ror     mpm_res,x
                dex
                bpl     stn_ror
                dey
                beq     main
stn_sub:        ldx     #(NUMSTRSIZE-2)
stn_subloop:    lda     nc_string+1,x
                cmp     #$8
                bmi     stn_nosub
                sbc     #$3
                sta     nc_string+1,x
stn_nosub:      dex
                bpl     stn_subloop
                bmi     stn_loop

main:
                ldx     #(NUMSIZE-1)
argloop:        lda     mpm_res,x
                sta     v_n,x
                dex
                bpl     argloop
                lda     #$01
                sta     v_x
                ldx     #(NUMSIZE-1)
                lda     #$00
initxloop:      sta     v_x,x
                dex
                bne     initxloop

mainloop:

; prepare arguments for multiplication:

                ldx     #(NUMSIZE-1)
sqrargloop:     lda     v_x,x
                sta     mpm_arg1,x
                sta     mpm_arg2,x
                dex
                bpl     sqrargloop

; do multiplication:

                lda     #$00
                ldx     #(NUMSIZE-1)
mul_clearloop:  sta     mpm_res,x
                dex
                bpl     mul_clearloop
                ldy     #(NUMSIZE*8)
mul_loop:       ldx     #(NUMSIZE-2)
                lsr     mpm_arg1+NUMSIZE-1
mul_rorloop:    ror     mpm_arg1,x
                dex
                bpl     mul_rorloop
                bcc     mul_noadd
                ldx     #($80-NUMSIZE)
                clc
mul_addloop:    lda     mpm_arg2+NUMSIZE+$80,x
                adc     mpm_res+NUMSIZE+$80,x
                sta     mpm_res+NUMSIZE+$80,x
                inx
                bpl     mul_addloop
mul_noadd:      ldx     #($81-NUMSIZE)
                asl     mpm_arg2
mul_rolloop:    rol     mpm_arg2+NUMSIZE+$80,x
                inx
                bpl     mul_rolloop
                dey
                bpl     mul_loop

; convert result to string:

                ldy     #NUMSTRSIZE
                lda     #$0
nts_fillzero:   sta     nc_string-1,y
                dey
                bne     nts_fillzero
                ldy     #(NUMSIZE*8)
nts_bcdloop:    ldx     #(NUMSTRSIZE-2)
nts_addloop:    lda     nc_string+1,x
                cmp     #$5
                bmi     nts_noadd
                adc     #$2
                sta     nc_string+1,x
nts_noadd:      dex
                bpl     nts_addloop
                asl     mpm_res
                ldx     #($ff-NUMSIZE+2)
nts_rol:        rol     mpm_res+NUMSIZE,x       ; + $100 w/o zp wraparound
                inx
                bne     nts_rol
                ldx     #(NUMSTRSIZE-2)
nts_rolloop:    lda     nc_string+1,x
                rol     a
                cmp     #$10
                and     #$f
                sta     nc_string+1,x
nts_rolnext:    dex
                bpl     nts_rolloop
                dey
                bne     nts_bcdloop
nts_scan:       cpx     #(NUMSTRSIZE-1)
                beq     nts_copydigits
                inx
                lda     nc_string,x
                beq     nts_scan
nts_copydigits: ora     #$30
                sta     nc_string,y
                iny
                inx
                cpx     #(NUMSTRSIZE)
                beq     strip0loop
                lda     nc_string,x
                bcc     nts_copydigits

; search for first non-0 character from the end of the string:

strip0loop:     dey
                lda     nc_string,y
                cmp     #$30
                beq     strip0loop

; decrement n for each digit:

founddigit:
                ldx     #($80-NUMSIZE)
                clc
decnloop:       lda     v_n+NUMSIZE+$80,x
                sbc     #$00
                sta     v_n+NUMSIZE+$80,x
                inx
                bpl     decnloop
                bcc     foundresult

                dey
                bmi     next_x
                lda     nc_string,y
                bne     founddigit

; increment x to calculate next square number:

next_x:
                ldx     #($80-NUMSIZE)
incxloop:       inc     v_x+NUMSIZE-$80,x
                bne     incxdone
                inx
                bpl     incxloop
incxdone:       jmp     mainloop

foundresult:    lda     nc_string,y
                jmp     $ffd2

```

... and here's the linker script for `ld65`:

```
MEMORY {
  LDADDR: start = $bffe, size = 2;
  CODE: start = $c000, size = $1000;
  ZPTMP: start = $0022, size = $0008;
  ZPFAC: start = $0057, size = $000f;
  ZPFAC2: start = $0069, size = $0004;
  ZPUSR: start = $00fb, size = $0004;
}

SEGMENTS {
  LDADDR: load = LDADDR;
  CODE: load = CODE;
  ZPTMP: load = ZPTMP, type = zp;
  ZPFAC: load = ZPFAC, type = zp;
  ZPFAC2: load = ZPFAC2, type = zp;
  ZPUSR: load = ZPUSR, type = zp;
}

```
> 3 votes

# Answer
# Perl 5, 59 + 1 (`-a`) = 60 bytes, LD=55

```
$j.=int reverse$_**2for 1..$_;$_--;say$j=~s/.{$_}(.).*/$1/r

```

Try it online!
> 2 votes

# Answer
# Java 8, (177 bytes) LD = 92 (Cracked by *@Arnauld*)

(Ive used this online LD-calculator.)

```
n->{String r="",t=r;for(int i=1,j;r.length()<=n+1;i++)if(Math.sqrt(i)%1==0){for(t="",j=(i+"").length();j>0;t+=(i+"").charAt(--j));r+=t.replaceAll("^0+","");}return r.charAt(n);}

```

This is probably not too hard if you simply golf this. :)

**Explanation:**

Try it here.

```
n->{                             // Method with integer parameter and character return-type
  String r="",                   //  Result-String, starting empty
         t=r;                    //  Temp-String, starting empty
  for(int i=1,j;                 //  Index-integers
      r.length()<=n+1;i++)       //  Loop (1) as long as the length is at least n+1
    if(Math.sqrt(i)%1==0){       //   If the current number `i` is a perfect square:
      for(t="",                  //    Reset the temp-String to empty
          j=(i+"").length();     //    Set `j` to the length of the current number
          j>0;                   //    Inner loop (2) as long as `j` is larger than 0
        t+=                      //     Append the temp-String with:
           (i+"").charAt(--j)    //     The digit of integer `i` at index `j-1`
                                 //     (by first decrease `j` with 1 with `--j`)
      );                         //    End of inner loop (2)
      r+=t                       //    And then append the temp-String to the result-String
          .replaceAll("^0+","");}//    after we've removed any leading zeroes
                                 //  End of loop (1) (implicit / single-line body)
  return r.charAt(n);            //  Return the `n`'th character of the result-String
}                                // End of method

```
> 2 votes

# Answer
# Octave, LD = 63, Cracked

```
@(t)[arrayfun(@(t)num2str(str2num(flip(num2str(t)))),(1:t).^2,'uni',0){:}](t)

```

Try it online!

The submission is 77 bytes, so you need to substitute quite a bit =)
> 2 votes

# Answer
# 6502 machine code (C64), LD = 1, safe

```
00 C0 20 FD AE A0 00 99 5B 00 C8 20 73 00 90 F7 99 5B 00 A2 0B CA 98 88 30 09
B9 5B 00 29 0F 95 5B 10 F2 95 5B CA 10 FB A0 20 A2 76 18 B5 E6 90 02 09 10 4A
95 E6 E8 10 F4 A2 03 76 69 CA 10 FB 88 F0 11 A2 09 B5 5C C9 08 30 04 E9 03 95
5C CA 10 F3 30 D6 A2 03 B5 69 95 57 CA 10 F9 A9 01 85 FB A2 03 A9 00 95 FB CA
D0 FB A2 03 B5 FB 95 22 95 26 CA 10 F7 A9 00 A2 03 95 69 CA 10 FB A0 20 A2 02
46 25 76 22 CA 10 FB 90 0C A2 7C 18 B5 AA 75 ED 95 ED E8 10 F7 A2 7D 06 26 36
AA E8 10 FB 88 10 DD A2 0B A9 00 95 5A CA D0 FB A0 20 A2 09 B5 5C C9 05 30 04
69 02 95 5C CA 10 F3 06 69 A2 FD 36 6D E8 D0 FB A2 09 B5 5C 2A C9 10 29 0F 95
5C CA 10 F4 88 D0 D7 E8 B5 5B F0 FB 09 30 99 5B 00 C8 E8 E0 0B F0 04 B5 5B 90
F1 88 B9 5B 00 C9 30 F0 F8 A2 7C 18 B5 DB E9 00 95 DB E8 10 F7 90 14 88 30 05
B9 5B 00 D0 EA A2 7C F6 7F D0 03 E8 10 F9 4C 68 C0 B9 5B 00 4C D2 FF

```

**Online demo**, usage: `sys49152,n` where `n` is the 0-indexed input.

---

**Intended solution:** (diff)

```
 B9 5B 00 29 0F 95 5B 10 F2 95 5B CA 10 FB A0 20 A2 76 18 B5 E6 90 02 09 10 4A
-95 E6 E8 10 F4 A2 03 76 69 CA 10 FB 88 F0 11 A2 09 B5 5C C9 08 30 04 E9 03 95
+95 E6 E8 10 F4 A2 03 76 69 CA 10 FB 88 F0 11 A2 09 B5 5C C9 08 90 04 E9 03 95
 5C CA 10 F3 30 D6 A2 03 B5 69 95 57 CA 10 F9 A9 01 85 FB A2 03 A9 00 95 FB CA

```

The `30` (opcode `bmi`) is replaced by `90` (opcode `bcc`). This corresponds to the following part in the assembler source:

```
stn_subloop:    lda     nc_string+1,x
                cmp     #$8
                bmi     stn_nosub       ; use bcc here for same result
                sbc     #$3
                sta     nc_string+1,x

```

It works because this code checks whether a number is smaller than 8. The `cmp` instruction performs a subtraction for that, setting the flags accordingly. So, if the accumulator holds a number smaller than 8, this underflows, clearing the carry flag, therefore the correct branch instruction is indeed `bcc`. `bmi` (branching when negative), as in the original code, just happens to work here as well, because the compared numbers are small enough, so the result of the subtraction ends up in the negative range (`$80-$ff`) when an underflow occurs.

**Online demo**

---

This is an improved/compacted version of my previous submission. Among some other tricks to reduce the size, it removes the useless code that was contained and allowed a kind of "simple"\*) crack. All in all, the size is reduced by 16 bytes. This time, it should be a bit harder to find the equivalent program with LD 1 :)

<sup>\*) probably still quite some work to find, of course :)</sup>

Again, here's the `ca65` assembler source, to help getting started with the code:

```
NUMSIZE         = 4     ; 32 bit integers ...
NUMSTRSIZE      = 11    ; need up to 11 characters for 0-terminated string

.segment "ZPUSR": zeropage
v_x:            .res    NUMSIZE         ; next number to be squared

.segment "ZPFAC": zeropage
v_n:            .res    NUMSIZE         ; input index (0-based), counts down
nc_string:      .res    NUMSTRSIZE      ; string buffer for numbers

.segment "ZPTMP": zeropage
mpm_arg1:       .res    NUMSIZE         ; arg1 for multiplication
mpm_arg2:       .res    NUMSIZE         ; arg2 for multiplication

.segment "ZPFAC2": zeropage
mpm_res:        .res    NUMSIZE         ; numeric result (mult and str convert)

; load address for creating a C64 .PRG file:

.segment "LDADDR"
                .word   $c000

.code

; first read number from command argument and convert to unsigned
; integer in little-endian:

                jsr     $aefd
                ldy     #$00
rn_loop:        sta     nc_string,y
                iny
                jsr     $73
                bcc     rn_loop
                sta     nc_string,y
                ldx     #NUMSTRSIZE
stn_copybcd:    dex
                tya
                dey
                bmi     stn_fillzero
                lda     nc_string,y
                and     #$f
                sta     nc_string,x
                bpl     stn_copybcd
stn_fillzero:   sta     nc_string,x
                dex
                bpl     stn_fillzero
                ldy     #(NUMSIZE*8)
stn_loop:       ldx     #($81-NUMSTRSIZE)
                clc
stn_rorloop:    lda     nc_string+NUMSTRSIZE+$80,x
                bcc     stn_skipbit
                ora     #$10
stn_skipbit:    lsr     a
                sta     nc_string+NUMSTRSIZE+$80,x
                inx
                bpl     stn_rorloop
                ldx     #(NUMSIZE-1)
stn_ror:        ror     mpm_res,x
                dex
                bpl     stn_ror
                dey
                beq     main
stn_sub:        ldx     #(NUMSTRSIZE-2)
stn_subloop:    lda     nc_string+1,x
                cmp     #$8
                bmi     stn_nosub
                sbc     #$3
                sta     nc_string+1,x
stn_nosub:      dex
                bpl     stn_subloop
                bmi     stn_loop

main:
                ldx     #(NUMSIZE-1)
argloop:        lda     mpm_res,x
                sta     v_n,x
                dex
                bpl     argloop
                lda     #$01
                sta     v_x
                ldx     #(NUMSIZE-1)
                lda     #$00
initxloop:      sta     v_x,x
                dex
                bne     initxloop

mainloop:

; prepare arguments for multiplication:

                ldx     #(NUMSIZE-1)
sqrargloop:     lda     v_x,x
                sta     mpm_arg1,x
                sta     mpm_arg2,x
                dex
                bpl     sqrargloop

; do multiplication:

                lda     #$00
                ldx     #(NUMSIZE-1)
mul_clearloop:  sta     mpm_res,x
                dex
                bpl     mul_clearloop
                ldy     #(NUMSIZE*8)
mul_loop:       ldx     #(NUMSIZE-2)
                lsr     mpm_arg1+NUMSIZE-1
mul_rorloop:    ror     mpm_arg1,x
                dex
                bpl     mul_rorloop
                bcc     mul_noadd
                ldx     #($80-NUMSIZE)
                clc
mul_addloop:    lda     mpm_arg2+NUMSIZE+$80,x
                adc     mpm_res+NUMSIZE+$80,x
                sta     mpm_res+NUMSIZE+$80,x
                inx
                bpl     mul_addloop
mul_noadd:      ldx     #($81-NUMSIZE)
                asl     mpm_arg2
mul_rolloop:    rol     mpm_arg2+NUMSIZE+$80,x
                inx
                bpl     mul_rolloop
                dey
                bpl     mul_loop

; convert result to string:

                ldx     #NUMSTRSIZE
                lda     #$0
nts_fillzero:   sta     nc_string-1,x
                dex
                bne     nts_fillzero
                ldy     #(NUMSIZE*8)
nts_bcdloop:    ldx     #(NUMSTRSIZE-2)
nts_addloop:    lda     nc_string+1,x
                cmp     #$5
                bmi     nts_noadd
                adc     #$2
                sta     nc_string+1,x
nts_noadd:      dex
                bpl     nts_addloop
                asl     mpm_res
                ldx     #($ff-NUMSIZE+2)
nts_rol:        rol     mpm_res+NUMSIZE,x       ; + $100 w/o zp wraparound
                inx
                bne     nts_rol
                ldx     #(NUMSTRSIZE-2)
nts_rolloop:    lda     nc_string+1,x
                rol     a
                cmp     #$10
                and     #$f
                sta     nc_string+1,x
nts_rolnext:    dex
                bpl     nts_rolloop
                dey
                bne     nts_bcdloop
nts_scan:       inx
                lda     nc_string,x
                beq     nts_scan
nts_copydigits: ora     #$30
                sta     nc_string,y
                iny
                inx
                cpx     #(NUMSTRSIZE)
                beq     strip0loop
                lda     nc_string,x
                bcc     nts_copydigits

; search for first non-0 character from the end of the string:

strip0loop:     dey
                lda     nc_string,y
                cmp     #$30
                beq     strip0loop

; decrement n for each digit:

founddigit:
                ldx     #($80-NUMSIZE)
                clc
decnloop:       lda     v_n+NUMSIZE+$80,x
                sbc     #$00
                sta     v_n+NUMSIZE+$80,x
                inx
                bpl     decnloop
                bcc     foundresult

                dey
                bmi     next_x
                lda     nc_string,y
                bne     founddigit

; increment x to calculate next square number:

next_x:
                ldx     #($80-NUMSIZE)
incxloop:       inc     v_x+NUMSIZE-$80,x
                bne     incxdone
                inx
                bpl     incxloop
incxdone:       jmp     mainloop

foundresult:    lda     nc_string,y
                jmp     $ffd2

```

... and here's the linker script for `ld65`:

```
MEMORY {
  LDADDR: start = $bffe, size = 2;
  CODE: start = $c000, size = $1000;
  ZPTMP: start = $0022, size = $0008;
  ZPFAC: start = $0057, size = $000f;
  ZPFAC2: start = $0069, size = $0004;
  ZPUSR: start = $00fb, size = $0004;
}

SEGMENTS {
  LDADDR: load = LDADDR;
  CODE: load = CODE;
  ZPTMP: load = ZPTMP, type = zp;
  ZPFAC: load = ZPFAC, type = zp;
  ZPFAC2: load = ZPFAC2, type = zp;
  ZPUSR: load = ZPUSR, type = zp;
}

```
> 2 votes

# Answer
## Lua : LD=1, cracked

```
i=1s=""while(#s<...+0)do s=s..((i*i)..""):reverse():gsub("(0+)(%d+)$","%2")i=i+1 end print(s:sub(...,...))

```

No fancy tricks here :)
> 1 votes

# Answer
# Mathematica, LD=43 cracked

```
Flatten[Table[(k=IntegerDigits)@FromDigits@Reverse@k[i^2],{i,10^4}]][[#]]&

```

Try it online!
> 1 votes

# Answer
# PHP, LD = 35 (Cracked)

1-indexed

```
<?while(strlen($s)<$argv[1])$s.=(int)strrev(++$i*$i);echo substr($s,$argv[1]-1,1);

```

Try it online!
> 1 votes

# Answer
# Python 3: LD = 9 | Cracked

```
lambda i:"".join(str(k*k+2*k+1)[::-1].lstrip("0")for k in range(i+1))[i]

```

This one should be fairly (very) easy to get :P
> 0 votes

# Answer
# Groovy, 61 bytes (LD = 23)

```
{(1..it).collect{0.valueOf("${it**2}".reverse())}.join()[it]}

```

Try it online!
> 0 votes

# Answer
# C++, LD = 159

0-indexed, input in `argv[1]`, compiled on GCC 7.2.0

```
#import<bits/stdc++.h>
char*h,b[1<<17],*q=b;int x,y;main(int,char**j){sscanf(j[1],"%d",&y);do{x++;q+=sprintf(h=q,"%d",x*x);while(*--q==48);std::reverse(h,++q);}while(q-b<=y);b[y+1]=0,printf(b+y);}

```
> 0 votes

---
Tags: number, sequence, cops-and-robbers, edit-distance
---


title: Finite tilings in one dimension

text:
# Question
Title: Finite tilings in one dimension
The purpose of this challenge is to determine if a collection of one-dimensonal pieces can be tiled to form a finite continuous chunk.

A **piece** is a non-empty, finite sequence of zeros and ones that starts and ends with a one. Some possible pieces are `1`, `101`, `1111`, `1100101`.

**Tiling** means arranging the pieces so that a single contiguous block of ones is formed. A one from one piece can occupy the place of a zero, but not of a one, from another piece.

Equivalently, if we view a one as being "solid material" and a zero as a "hole", the pieces should fit so as to form a single stretch, without leaving any holes.

To form a tiling, pieces can only be **shifted** along their one-dimensional space. (They cannot be split, or reflected). Each piece is used exactly once.

# Examples

The three pieces `101`, `11`, `101` can be tiled as shown in the following, where each piece is represented with the required shift:

```
  101
11
   101

```

so the obtained tiling is

```
111111

```

As a second example, the pieces `11011` and `1001101` cannot be tiled. In particular, the shift

```
 11011
1001101

```

is not valid because there are two ones that collide; and

```
11011
  1001101

```

is not valid because the result would contain a zero.

# Additional rules

The **input** is a collection of one or more pieces. Any reasonable format is allowed; for example:

* A list of strings, where each string can contain two different, consistent characters;
* Several arrays, where each array contains the positions of ones for a piece;
* A list of (odd) integers such the binary representation of each number defines a piece.

The **output** should be a truthy value if a tiling is possible, and a falsy value otherwise. Output values need not be consistent; that is, they can be different for different inputs.

Programs or functions are allowed, in any programming language. Standard loopholes are forbidden.

Shortest code in bytes wins.

# Test cases

Each input is on a different line

### Truthy

```
1
111
1, 1
11, 111, 1111
101, 11, 1
101, 11, 101
10001, 11001, 10001
100001, 1001, 1011
10010001, 1001, 1001, 101
10110101, 11001, 100001, 1
110111, 100001, 11, 101
1001101, 110111, 1, 11, 1

```

### Falsy

```
101
101, 11
1, 1001
1011, 1011
11011, 1001101
1001, 11011, 1000001
1001, 11011, 1000001, 10101

```

# Answer
# Jelly, 15 bytes

```
+"FṢIP
FSṗLç€ċ1

```

Takes a list of indices and returns a positive integer (truthy) or **0** (falsy).

Try it online! or verify most test cases.
> 4 votes

# Answer
# JavaScript (ES6), ~~74~~ ~~73~~ 70 bytes

Takes input as an array of 32-bit integers. Returns a boolean.

```
f=([n,...a],x)=>n?[...f+''].some(_=>n&&!(x&n)&f(a,x|n,n<<=1)):!(x&-~x)

```

Or **66 bytes** with inverted truthy/falsy values:

```
f=([n,...a],x)=>n?[...Array(32)].every(_=>x&n|f(a,x|n,n*=2)):x&-~x

```

### Test cases

```
f=([n,...a],x)=>n?[...f+''].some(_=>n&&!(x&n)&f(a,x|n,n<<=1)):!(x&-~x)

console.log('[Truthy]')
console.log(f([0b1]))
console.log(f([0b111]))
console.log(f([0b1,0b1]))
console.log(f([0b11,0b111,0b1111]))
console.log(f([0b101,0b11,0b1]))
console.log(f([0b101,0b11,0b101]))
console.log(f([0b10001,0b11001,0b10001]))
console.log(f([0b100001,0b1001,0b1011]))
console.log(f([0b10010001,0b1001,0b1001,0b101]))
console.log(f([0b10110101,0b11001,0b100001,0b1]))
console.log(f([0b110111,0b100001,0b11,0b101]))
console.log(f([0b1001101,0b110111,0b1,0b11,0b1]))

console.log('[Falsy]')
console.log(f([0b101]))
console.log(f([0b101,0b11]))
console.log(f([0b1,0b1001]))
console.log(f([0b1011,0b1011]))
console.log(f([0b11011,0b1001101]))
console.log(f([0b1001,0b11011,0b1000001]))
console.log(f([0b1001,0b11011,0b1000001,0b10101]))
```

### How?

```
f = (                       // f = recursive function taking:
  [n, ...a],                //   n = next integer, a = array of remaining integers
  x                         //   x = solution bitmask, initially undefined
) =>                        //
  n ?                       // if n is defined:
    [... f + ''].some(_ =>  //   iterate 32+ times:
      n &&                  //     if n is not zero:
        !(x & n)            //       if x and n have some bits in common,
        &                   //       force invalidation of the following result
        f(                  //       do a recursive call with:
          a,                //         the remaining integers
          x | n,            //         the updated bitmask
          n <<= 1           //         and update n for the next iteration
        )                   //       end of recursive call
    )                       //   end of some()
  :                         // else (all integers have been processed):
    !(x & -~x)              //   check that x is a continuous chunk of 1's

```
> 8 votes

# Answer
# Husk, 16 bytes

```
V§=OŀF×+ṠṀṪ+oŀṁ▲

```

Takes a list of lists of 1-based indices. Try it online!

## Explanation

```
V§=OŀF×+ṠṀṪ+oŀṁ▲  Implicit input, say x=[[1,3],[1]]
              ṁ▲  Sum of maxima: 4
            oŀ    Lowered range: r=[0,1,2,3]
        ṠṀ        For each list in x,
          Ṫ+      create addition table with r: [[[1,3],[2,4],[3,5],[4,6]],
                                                 [[1],[2],[3],[4]]]
     F×+          Reduce by concatenating all combinations: [[1,3,1],[1,3,2],...,[4,6,4]]
V                 1-based index of first list y
    ŀ             whose list of 1-based indices [1,2,...,length(y)]
 §=               is equal to
   O              y sorted: 2

```
> 4 votes

# Answer
# Jelly, 16 bytes

```
FLḶ0ẋ;þ⁸ŒpS€P€1e

```

A monadic link taking a list of lists of ones and zeros returning either `1` (truthy) or `0` (falsey).

**Try it online!** or see a test-suite (shortened - first 6 falseys followed by first eight truthys since the length four ones take too long to include due to the use of the Cartesian product).

### How?

```
FLḶ0ẋ;þ⁸ŒpS€P€1e - Link: list of lists, tiles
F                - flatten (the list of tiles into a single list)
 L               - length (gets the total number of 1s and zeros in the tiles)
  Ḷ              - lowered range = [0,1,2,...,that-1] (how many zeros to try to prepend)
   0             - literal zero
    ẋ            - repeat = [[],[0],[0,0],...[0,0,...,0]] (the zeros to prepend)
       ⁸         - chain's left argument, tiles
      þ          - outer product with:
     ;           -   concatenation (make a list of all of the zero-prepended versions)

        Œp       - Cartesian product (all ways that could be chosen, including man
                 -   redundant ones like prepending n-1 zeros to every tile)
          S€     - sum €ach (good yielding list of only ones)
            P€   - product of €ach (good yielding 1, others yielding 0 or >1)
              1  - literal one
               e - exists in that? (1 if so 0 if not)

```
> 3 votes

# Answer
# Jelly, 16 bytes

```
FLḶ0ẋ;þµŒpSP$€1e

```

Try it online!

-1 byte thanks to Mr. Xcoder

I developed this completely independently of Jonathan Allan but now looking at his is exactly the same:
> 2 votes

# Answer
# Python 2, 159 bytes

```
lambda x:g([0]*sum(map(sum,x)),x)
g=lambda z,x:x and any(g([a|x[0][j-l]if-1<j-l<len(x[0])else a for j,a in enumerate(z)],x[1:])for l in range(len(z)))or all(z)

```

Try it online!
> 2 votes

# Answer
# , 74 bytes

```
f=:3 :'*+/1=*/"1+/"2(l{."1 b)|.~"1 0"_ 1>,{($,y)#<i.l=:+/+/b=:>,.&.":&.>y'

```

I might try to make it tacit later, but for now it's an explicit verb. I'll explain the ungolfed version. It takes a list of boxed integers and returns `1` (truthy) or `0` (falsy).

```
This will be my test case, a list of boxed integers:
   ]a=:100001; 1001; 1011
┌──────┬────┬────┐
│100001│1001│1011│
└──────┴────┴────┘
b is the rectangular array from the input, binary digits. Shorter numbers are padded
with trailing zeroes:
   ]b =: > ,. &. ": &.> a   NB. Unbox each number, convert it to a list of digits
1 0 0 0 0 1
1 0 0 1 0 0
1 0 1 1 0 0

l is the total number of 1s in the array:
   ]l=: +/ +/ b             NB. add up all rows, find the sum of the resulting row)
7

r contains all possible offsets needed for rotations of each row:
   r=: > , { ($,a) # < i.l  NB. a catalogue of all triplets (in this case, the list
has 3 items) containing the offsets from 0 to l:
0 0 0
0 0 1
0 0 2
0 0 3
0 0 4
 ...
6 6 3
6 6 4
6 6 5
6 6 6

m is the array after all possible rotations of the rows of b by the offsets in r.
But I first extend each row of b to the total length l:
   m=: r |."0 1"1 _ (l {."1 b)  NB. rotate the extended rows of b with offsets in r,
ranks adjusted

For example 14-th row of the offsets array applied to b:
    13{r
0 1 6
   13{m
1 0 0 0 0 1 0
0 0 1 0 0 0 1
0 1 0 1 1 0 0

Finally I add the rows for each permutation, take the product to check if it's all 1, and
check if there is any 1 in each permuted array.
   * +/ 1= */"1 +/"2 m
1

```

Try it online!
> 1 votes

---
Tags: code-golf, decision-problem, binary, tiling
---


title: Golf my "pre-golfed" C

text:
# Question
Title: Golf my "pre-golfed" C
## Background

For my submissions in C, I need a processing tool. Like in many other languages, whitespace is mostly irrelevant in C source (but not always!) -- still makes the code much more comprehensible for humans. A fully golfed C program that doesn't contain a single redundant whitespace often is barely readable.

Therefore, I like to write my code in C for a submission including whitespace and sometimes comments, so the program keeps a comprehensible structure while writing. The last step is to remove all comments and redundant whitespace. This is a tedious and mindless task which really should be done by an intern a computer program.

## Task

Write a program or function that eliminates comments and redundant whitespace from some "pre-golfed" C source according to the following rules:

* A `\` (backslash) as the very last character in a line is a *line continuation*. If you find this, you must treat the following line as part of the same *logical line* (you could for example remove the `\` and the following `\n` (newline) completely before doing anything else)
* Comments will only use the one-line format, starting with `//`. So to remove them, you ignore the rest of the logical line wherever you encounter `//` outside a *string literal* (see below).
* Whitespace characters are  (space), `\t` (tab) and `\n` (newline, so here the end of a logical line).
* When you find a sequence of whitespace, examine the non-whitespace characters surrounding it. If

+ both of them are alphanumeric or underscore (range `[a-zA-Z0-9_]`) or
    + both are `+` or
    + both are `-` or
    + the preceeding one is `/` and the following one is `*`

then replace the sequence with a single space () character.

Otherwise, eliminate the sequence completely.

This rule has *some exceptions*:

+ *Preprocessor directives* must appear on their own lines in your output. A preprocessor directive is a line starting with `#`.
    + Inside a *string literal* or *character literal*, you shouldn't remove any whitespace. Any `"` (double-quote) / `'` (single-quote) that isn't directly preceeded by an odd number of backslashes (`\`) starts or ends a *string literal* / *character literal*. You're guaranteed that string and character literals end on the same line they started. *string literals* and *character literals* cannot be nested, so a `'` inside a *string literal*, as well as a `"` inside a *character literal* don't have any special meaning.

### I/O specification

Input and output must be either character sequences (strings) including newline characters or arrays/lists of strings that don't contain newline characters. If you choose to use arrays/lists, each element represents a line, so the newlines are *implicit* after each element.

You may assume the input is a valid C program source code. This also means it only contains printable ASCII characters, tabs and newlines. Undefined behavior on malformed input is allowed.

**Leading and trailing whitespace / empty lines** are **not allowed**.

### Test cases

1. input

```
main() {
    printf("Hello, World!"); // hi
}

```

output

```
main(){printf("Hello, World!");}

```
2. input

```
#define max(x, y) \
    x > y ? x : y
#define I(x) scanf("%d", &x)
a;
b; // just a needless comment, \
        because we can!
main()
{
    I(a);
    I(b);
    printf("\" max \": %d\n", max(a, b));
}

```

output

```
#define max(x,y)x>y?x:y
#define I(x)scanf("%d",&x)
a;b;main(){I(a);I(b);printf("\" max \": %d\n",max(a,b));}

```
3. input

```
x[10];*c;i;
main()
{
    int _e;
    for(; scanf("%d", &x) > 0 && ++_e;);
    for(c = x + _e; c --> x; i = 100 / *x, printf("%d ", i - --_e));
}

```

output

```
x[10];*c;i;main(){int _e;for(;scanf("%d",&x)>0&&++_e;);for(c=x+_e;c-->x;i=100/ *x,printf("%d ",i- --_e));}

```
4. input

```
x;
#include <stdio.h>
int main()
{
    puts("hello // there");
}

```

output

```
x;
#include<stdio.h>
int main(){puts("hello // there");}

```
5. input (a real-world example)

```
// often used functions/keywords:
#define P printf(
#define A case
#define B break

// loops for copying rows upwards/downwards are similar -> macro
#define L(i, e, t, f, s) \
        for (o=i; o e;){ strcpy(l[o t], l[o f]); c[o t]=c[s o]; }

// range check for rows/columns is similar -> macro
#define R(m,o) { return b<1|b>m ? m o : b; }

// checking for numerical input is needed twice (move and print command):
#define N(f) sscanf(f, "%d,%d", &i, &j) || sscanf(f, ",%d", &j)

// room for 999 rows with each 999 cols (not specified, should be enough)
// also declare "current line pointers" (*L for data, *C for line length),
// an input buffer (a) and scratch variables
r, i, j, o, z, c[999], *C, x=1, y=1;
char a[999], l[999][999], (*L)[999];

// move rows down from current cursor position
D()
{
    L(r, >y, , -1, --)
    r++ ? strcpy(l[o], l[o-1]+--x), c[o-1]=x, l[o-1][x]=0 : 0;
    c[y++] = strlen(l[o]);
    x=1;
}

// move rows up, appending uppermost to current line
U()
{
    strcat(*L, l[y]);
    *C = strlen(*L);
    L(y+1, <r, -1, , ++)
    --r;
    *l[r] = c[r] = 0;
}

// normalize positions, treat 0 as max
X(b) R(c[y-1], +1)
Y(b) R(r, )

main()
{
    for(;;) // forever
    {
        // initialize z as current line index, the current line pointers,
        // i and j for default values of positioning
        z = i = y;
        L = l + --z;
        C = c + z;
        j = x;

        // prompt:
        !r || y/r && x > *C
            ? P "end> ")
            : P "%d,%d> ", y, x);

        // read a line of input (using scanf so we don't need an include)
        scanf("%[^\n]%*c", a)

            // no command arguments -> make check easier:
            ? a[2] *= !!a[1],

            // numerical input -> have move command:
            // calculate new coordinates, checking for "relative"
            N(a)
                ? y = Y(i + (i<0 | *a=='+') * y)
                    , x = X(j + (j<0 || strchr(a+1, '+')) * x)
                :0

            // check for empty input, read single newline
            // and perform <return> command:
            : ( *a = D(), scanf("%*c") );

        switch(*a)
        {
            A 'e':
                y = r;
                x = c[r-1] + 1;
                B;

            A 'b':
                y = 1;
                x = 1;
                B;

            A 'L':
                for(o = y-4; ++o < y+2;)
                    o<0 ^ o<r && P "%c%s\n", o^z ? ' ' : '>', l[o]);
                for(o = x+1; --o;)
                    P " ");
                P "^\n");
                B;

            A 'l':
                puts(*L);
                B;

            A 'p':
                i = 1;
                j = 0;
                N(a+2);
                for(o = Y(i)-1; o<Y(j); ++o)
                    puts(l[o]);
                B;

            A 'A':
                y = r++;
                strcpy(l[y], a+2);
                x = c[y] = strlen(a+2);
                ++x;
                ++y;
                B;

            A 'i':
                D();
                --y;
                x=X(0);
                // Commands i and r are very similar -> fall through
                // from i to r after moving rows down and setting
                // position at end of line:

            A 'r':
                strcpy(*L+x-1, a+2);
                *C = strlen(*L);
                x = 1;
                ++y > r && ++r;
                B;

            A 'I':
                o = strlen(a+2);
                memmove(*L+x+o-1, *L+x-1, *C-x+1);
                *C += o;
                memcpy(*L+x-1, a+2, o);
                x += o;
                B;

            A 'd':
                **L ? **L = *C = 0, x = 1 : U();
                y = y>r ? r : y;
                B;

            A 'j':
                y<r && U();
        }
    }
}

```

output

```
#define P printf(
#define A case
#define B break
#define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];}
#define R(m,o){return b<1|b>m?m o:b;}
#define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j)
r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];D(){L(r,>y,,-1,--)r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;c[y++]=strlen(l[o]);x=1;}U(){strcat(*L,l[y]);*C=strlen(*L);L(y+1,<r,-1,,++)--r;*l[r]=c[r]=0;}X(b)R(c[y-1],+1)Y(b)R(r,)main(){for(;;){z=i=y;L=l+--z;C=c+z;j=x;!r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);scanf("%[^\n]%*c",a)?a[2]*=!!a[1],N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:(*a=D(),scanf("%*c"));switch(*a){A'e':y=r;x=c[r-1]+1;B;A'b':y=1;x=1;B;A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ':'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;A'l':puts(*L);B;A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;A'i':D();--y;x=X(0);A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;A'j':y<r&&U();}}}

```

---

This is , so shortest (in bytes) valid answer wins.

# Answer
> 4 votes
# Pip, ~~148~~ ~~135~~ ~~133~~ 138 bytes

```
aRM"\
"R`("|').*?(?<!\\)(\\\\)*\1`{lPBaC:++i+191}R[`//.*``#.*`{X*aJw.`(?=`}.')M[A`\w`RL2"++""--""/*"]w`¶+`'·C(192+,#l)][x_WR'¶{aRw'·}xnsl]

```

Bytes are counted in CP-1252, so  and `·` are one byte each. Note that this expects the C code as a single command-line argument, which (on an actual command line) would require the use of copious escape sequences. It's much easier at Try it online!

## Explanation of slightly ungolfed version

The code does a bunch of replacement operations, with a couple tricks.

### Backslash continuations

We `RM` all occurrences of the literal string

```
"\
"

```

that is, backslash followed by newline.

### String and character literals

We use a regex replacement with a callback function:

```
`("|').*?(?<!\\)(\\\\)*\1`

{
 lPBa
 C(++i + 191)
}

```

The regex matches a single or double quote, followed by a non-greedy `.*?` that matches 0 or more characters, as few as possible. We have a negative lookbehind to ensure that the previous character was not a backslash; then we match an even number of backslashes followed by the opening delimiter again.

The callback function takes the string/character literal and pushes it to the back of the list `l`. It then returns a character starting with character code 192 (`À`) and increasing with each literal replaced. Thus, code is transformed like so:

```
printf("%c", '\'');

printf(À, Á);

```

These replacement characters are guaranteed not to occur in the source code, which means we can unambiguously back-substitute them later.

### Comments

```
`//.*`

x

```

The regex matches `//` plus everything up to the newline and replaces with `x` (preset to the empty string).

### Preprocessor directives

```
`#.*`

_WR'¶

```

Wraps runs of non-newline characters starting with a pound sign in .

### Spaces that should not be eliminated

```
{
 (
  X*a J w.`(?=`
 ) . ')
}
M
[
 A`\w` RL 2
 "++"
 "--"
 "/*"
]

{
 a R w '·
}

```

There's a lot going on here. The first part generates this list of regexes to replace:

```
[
 `(?a)\w\s+(?=(?a)\w)`  Whitespace surrounded by [a-zA-Z_]
 `\+\s+(?=\+)`          Whitespace surrounded by +
 `\-\s+(?=\-)`          Whitespace surrounded by -
 `\/\s+(?=\*)`          Whitespace surrounded by / *
]

```

Note the use of lookaheads to match, for example, just the `e`  in `define P printf`. That way this match doesn't consume the `P`, which means the next match can use it.

We generate this list of regexes by mapping a function to a list, where the list contains

```
[
 [`(?a)\w` `(?a)\w`]
 "++"
 "--"
 "/*"
]

```

and the function does this to each element:

```
(X*aJw.`(?=`).')
 X*a              Map unary X to elements/chars a: converts to regex, escaping as needed
                  Regexes like `\w` stay unchanged; strings like "+" become `\+`
    J             Join the resulting list on:
     w             Preset variable for `\s+`
      .`(?=`       plus the beginning of the lookahead syntax
(           ).')  Concatenate the closing paren of the lookahead

```

Once we have our regexes, we replace their occurrences with this callback function:

```
{aRw'·}

```

which replaces the run of whitespace in each match with `·`.

### Whitespace elimination and cleanup

```
[w `¶+` '·]

[x n s]

```

Three successive replacements substitute remaining runs of whitespace (`w`) for empty string (`x`), runs of  for newline, and `·` for space.

### Back-substitution of string and character literals

```
C(192+,#l)

l

```

We construct a list of all the characters we used as substitutions for literals by taking `192 + range(len(l))` and converting to characters. We then can replace each of these with its associated literal in `l`.

And that's it! The resulting string is autoprinted.

# Answer
> 7 votes
# Haskell, ~~327~~ ~~360~~ ~~418~~ 394 bytes

```
g.(m.w.r.r=<<).lines.f
n:c:z="\n#_0123456789"++['A'..'Z']++['a'..'z']
(!)x=elem x
f('\\':'\n':a)=f a
f(a:b)=a:f b
f a=a
m('#':a)=c:a++[n]
m a=a
g(a:'#':b)=a:[n|a/=n]++c:g b
g(a:b)=a:g b
g a=a
s=span(!" \t")
r=reverse.snd.s
l n(a:b)d|a==d,n=a:w(snd$s b)|1>0=a:l(not$n&&a=='\\')b d
w('/':'/':_)=[]
w(a:b)|a!"\"'"=a:l(1>0)b a|(p,q:u)<-s b=a:[' '|p>"",a!z&&q!z||[a,q]!words"++ -- /*"]++w(q:u)
w a=a

```

Try it online!

This was a lot of fun to write! First the `f` function comes through and removes all the backslashes at the end of lines then `lines` breaks it into a list of strings at the newlines. Then we map a bunch of functions onto the lines and concatenate them all back together. Those functions: strip whitespace from the left (`t`) and from the right (`r.t.r` where `r` is `reverse`); remove whitespace from the middle, ignoring string and character literals as well as removing comments (`w`); and finally adds a newline character to the end if the line starts with a #. After all the lines are concatenated back together `g` looks for # characters and ensures they are preceded by a newline.

`w` is a little complex so I'll explain it further. First I check for "//" since in `w` I know I'm not in a string literal I know this is a comment so I drop the rest of the line. Next I check if the head is a delimiter for a string or character literal. If it is I prepend it and pass the baton to `l` which runs through the characters, tracking the "escape" state with `n` which will be true if there have been an even number of consecutive slashes. When `l` detects a delimiter and isn't in the escape state it passes the baton back to `w`, trimming to eliminate whitespace after the literal because `w` expects the first character to not be whitespace. When `w` doesn't find a delimiter it uses span to look for whitespace in the tail. If there's any it checks if the characters around it are cannot be brought into contact and inserts a space if so. Then it recurs after the whitespace is ended. If there was no whitespace no space is inserted and it moves on anyway.

EDIT: Thanks a lot to @DLosc for pointing out a bug in my program that actually led to a way for me to shorten it as well! Hooray for pattern matching!

EDIT2: I'm an idiot who didn't finish reading the spec! Thanks again DLosc for pointing that out!

EDIT3: Just noticed some annoying type reduction thing that turned `e=elem` into `Char->[Char]->Bool` for some reason, thus breaking on `e[a,q]`. I had to add a type signature to force it to be correct. Does anyone know how I could fix that? I've never had this problem in Haskell before. TIO

EDIT4: quick fix for bug @FelixPalmen showed me. I might try to golf it down later when I have some time.

EDIT5: -24 bytes thanks to @Lynn! Thank you! I didn't know you could assign things on the global scope using pattern matching like `n:c:z=...` that's really cool! Also good idea making an operator for `elem` wish I'd thought of that.

# Answer
> 3 votes
# C, ~~497~~ ~~494~~ ~~490~~ 489 bytes

Since we're processing C, let's do it *using* C! Function `f()` takes input from char pointer `p` and outputs to pointer `q`, and assumes that the input is in ASCII:

```
#define O*q++
#define R (r=*p++)
#define V(c)(isalnum(c)||c==95)
char*p,*q,r,s,t;d(){isspace(r)?g():r==47&&*p==r?c(),g():r==92?e():(O=s=r)==34?b():r==39?O=R,a():r?a():(O=r);}a(){R;d();}b(){((O=R)==34?a:r==92?O=R,b:b)();}c(){while(R-10)p+=r==92;}e(){R-10?s=O=92,O=r,a():h();}j(){(!isspace(R)?r==47&&*p==r?c(),j:(t=r==35,d):j)();}f(){t=*p==35;j();}i(){V(s)&&V(r)||s==47&&r==42||(s==43||s==45)&&r==s&&*p==s?O=32:0;d();}h(){isspace(R)?g():i();}g(){(r==10?t?O=r,j:*p==35?s-10?s=O=r,j:0:h:h)();}

```

We assume that the file is well-formed - string and character literals are closed, and if there's a comment on the final line, there must be a newline to close it.

## Explanation

The pre-golfed version is only slightly more legible, I'm afraid:

```
#define O *q++=
#define R (r=*p++)
#define V(c)(isalnum(c)||c=='_')
char*p,*q,r,s,t;
d(){isspace(r)?g():r=='/'&&*p==r?c(),g():r=='\\'?e():(O s=r)=='"'?b():r=='\''?O R,a():r?a():(O r);}
a(){R;d();}
b(){((O R)=='"'?a:r=='\\'?O R,b:b)();}
c(){while(R!='\n')p+=r=='\\';}
e(){R!='\n'?s=O'\\',O r,a():h();}
j(){(!isspace(R)?r=='/'&&*p==r?c(),j:(t=r=='#',d):j)();}
f(){t=*p=='#';j();}
i(){V(s)&&V(r)||s=='/'&&r=='*'||(s=='+'||s=='-')&&r==s&&*p==s?O' ':0;d();}
h(){isspace(R)?g():i();}
g(){(r=='\n'?t?O r,j:*p=='#'?s!='\n'?s=O r,j:0:h:h)();}

```

It implements a state machine by tail recursion. The helper macros and variables are

* **`O`** for **o**utput
* **`R`** to **r**ead input into `r`
* **`V`** to determine **v**alid identifier characters (since `!isalnum('_')`)
* **`p`** and **`q`** \- I/O pointers as described
* **`r`** \- last character to be **r**ead
* **`s`** \- **s**aved recent non-whitespace character
* **`t`** \- **t**ag when working on a preprocessor directive

Our states are

* **`a()`** \- normal C code
* **`b()`** \- string literal
* **`c()`** \- comment
* **`d()`** \- normal C code, after reading `r`
* **`e()`** \- escape sequence
* **`f()`** \- initial state (main function)
* **`g()`** \- in whitespace
* **`h()`** \- in whitespace - dispatch to `g()` or `i()`
* **`i()`** \- immediately after whitespace - do we need to insert a space character?
* **`j()`** \- initial whitespace - never insert a space character

## Test program

```
#define DEMO(code)                              \
    do {                                        \
        char in[] = code;                       \
        char out[sizeof in];                    \
        p=in;q=out;f();                         \
        puts("vvvvvvvvvv");                     \
        puts(out);                              \
        puts("^^^^^^^^^^");                     \
    } while (0)

#include<stdio.h>
#include<stdlib.h>
int main()
{
    DEMO(
         "main() {\n"
         "    printf(\"Hello, World!\"); // hi\n"
         "}\n"
         );
    DEMO(
         "#define max(x, y)                               \\\n"
         "    x > y ? x : y\n"
         "#define I(x) scanf(\"%d\", &x)\n"
         "a;\n"
         "b; // just a needless comment, \\\n"
         "        because we can!\n"
         "main()\n"
         "{\n"
         "    I(a);\n"
         "    I(b);\n"
         "    printf(\"\\\" max \\\": %d\\n\", max(a, b));\n"
         "}\n"
         );
    DEMO(
         "x[10];*c;i;\n"
         "main()\n"
         "{\n"
         "    int _e;\n"
         "    for(; scanf(\"%d\", &x) > 0 && ++_e;);\n"
         "    for(c = x + _e; c --> x; i = 100 / *x, printf(\"%d \", i - --_e));\n"
         "}\n"
         );
    DEMO(
         "// often used functions/keywords:\n"
         "#define P printf(\n"
         "#define A case\n"
         "#define B break\n"
         "\n"
         "// loops for copying rows upwards/downwards are similar -> macro\n"
         "#define L(i, e, t, f, s) \\\n"
         "        for (o=i; o e;){ strcpy(l[o t], l[o f]); c[o t]=c[s o]; }\n"
         "\n"
         "// range check for rows/columns is similar -> macro\n"
         "#define R(m,o) { return b<1|b>m ? m o : b; }\n"
         "\n"
         "// checking for numerical input is needed twice (move and print command):\n"
         "#define N(f) sscanf(f, \"%d,%d\", &i, &j) || sscanf(f, \",%d\", &j)\n"
         "\n"
         "// room for 999 rows with each 999 cols (not specified, should be enough)\n"
         "// also declare \"current line pointers\" (*L for data, *C for line length),\n"
         "// an input buffer (a) and scratch variables\n"
         "r, i, j, o, z, c[999], *C, x=1, y=1;\n"
         "char a[999], l[999][999], (*L)[999];\n"
         "\n"
         "// move rows down from current cursor position\n"
         "D()\n"
         "{\n"
         "    L(r, >y, , -1, --)\n"
         "    r++ ? strcpy(l[o], l[o-1]+--x), c[o-1]=x, l[o-1][x]=0 : 0;\n"
         "    c[y++] = strlen(l[o]);\n"
         "    x=1;\n"
         "}\n"
         "\n"
         "// move rows up, appending uppermost to current line\n"
         "U()\n"
         "{\n"
         "    strcat(*L, l[y]);\n"
         "    *C = strlen(*L);\n"
         "    L(y+1, <r, -1, , ++)\n"
         "    --r;\n"
         "    *l[r] = c[r] = 0;\n"
         "}\n"
         "\n"
         "// normalize positions, treat 0 as max\n"
         "X(b) R(c[y-1], +1)\n"
         "Y(b) R(r, )\n"
         "\n"
         "main()\n"
         "{\n"
         "    for(;;) // forever\n"
         "    {\n"
         "        // initialize z as current line index, the current line pointers,\n"
         "        // i and j for default values of positioning\n"
         "        z = i = y;\n"
         "        L = l + --z;\n"
         "        C = c + z;\n"
         "        j = x;\n"
         "\n"
         "        // prompt:\n"
         "        !r || y/r && x > *C\n"
         "            ? P \"end> \")\n"
         "            : P \"%d,%d> \", y, x);\n"
         "\n"
         "        // read a line of input (using scanf so we don't need an include)\n"
         "        scanf(\"%[^\\n]%*c\", a)\n"
         "\n"
         "            // no command arguments -> make check easier:\n"
         "            ? a[2] *= !!a[1],\n"
         "\n"
         "            // numerical input -> have move command:\n"
         "            // calculate new coordinates, checking for \"relative\"\n"
         "            N(a)\n"
         "                ? y = Y(i + (i<0 | *a=='+') * y)\n"
         "                    , x = X(j + (j<0 || strchr(a+1, '+')) * x)\n"
         "                :0\n"
         "\n"
         "            // check for empty input, read single newline\n"
         "            // and perform <return> command:\n"
         "            : ( *a = D(), scanf(\"%*c\") );\n"
         "\n"
         "        switch(*a)\n"
         "        {\n"
         "            A 'e':\n"
         "                y = r;\n"
         "                x = c[r-1] + 1;\n"
         "                B;\n"
         "\n"
         "            A 'b':\n"
         "                y = 1;\n"
         "                x = 1;\n"
         "                B;\n"
         "\n"
         "            A 'L':\n"
         "                for(o = y-4; ++o < y+2;)\n"
         "                    o<0 ^ o<r && P \"%c%s\\n\", o^z ? ' ' : '>', l[o]);\n"
         "                for(o = x+1; --o;)\n"
         "                    P \" \");\n"
         "                P \"^\\n\");\n"
         "                B;\n"
         "\n"
         "            A 'l':\n"
         "                puts(*L);\n"
         "                B;\n"
         "\n"
         "            A 'p':\n"
         "                i = 1;\n"
         "                j = 0;\n"
         "                N(a+2);\n"
         "                for(o = Y(i)-1; o<Y(j); ++o)\n"
         "                    puts(l[o]);\n"
         "                B;\n"
         "\n"
         "            A 'A':\n"
         "                y = r++;\n"
         "                strcpy(l[y], a+2);\n"
         "                x = c[y] = strlen(a+2);\n"
         "                ++x;\n"
         "                ++y;\n"
         "                B;\n"
         "\n"
         "            A 'i':\n"
         "                D();\n"
         "                --y;\n"
         "                x=X(0);\n"
         "                // Commands i and r are very similar -> fall through\n"
         "                // from i to r after moving rows down and setting\n"
         "                // position at end of line:\n"
         "\n"
         "            A 'r':\n"
         "                strcpy(*L+x-1, a+2);\n"
         "                *C = strlen(*L);\n"
         "                x = 1;\n"
         "                ++y > r && ++r;\n"
         "                B;\n"
         "\n"
         "            A 'I':\n"
         "                o = strlen(a+2);\n"
         "                memmove(*L+x+o-1, *L+x-1, *C-x+1);\n"
         "                *C += o;\n"
         "                memcpy(*L+x-1, a+2, o);\n"
         "                x += o;\n"
         "                B;\n"
         "\n"
         "            A 'd':\n"
         "                **L ? **L = *C = 0, x = 1 : U();\n"
         "                y = y>r ? r : y;\n"
         "                B;\n"
         "\n"
         "            A 'j':\n"
         "                y<r && U();\n"
         "        }\n"
         "    }\n"
         "}\n";);
}

```

This produces

> ```
> main(){printf("Hello, World!");}
>
> ```

> ```
> #define max(x,y)x>y?x:y
> #define I(x)scanf("%d",&x)
> a;b;main(){I(a);I(b);printf("\" max \": %d\n",max(a,b));}
>
> ```

> ```
> x[10];*c;i;main(){int _e;for(;scanf("%d",&x)>0&&++_e;);for(c=x+_e;c-->x;i=100/ *x,printf("%d ",i- --_e));}
>
> ```

> ```
> #define P printf(
> #define A case
> #define B break
> #define L(i,e,t,f,s)for(o=i;o e;){strcpy(l[o t],l[o f]);c[o t]=c[s o];}
> #define R(m,o){return b<1|b>m?m o:b;}
> #define N(f)sscanf(f,"%d,%d",&i,&j)||sscanf(f,",%d",&j)
> r,i,j,o,z,c[999],*C,x=1,y=1;char a[999],l[999][999],(*L)[999];D(){L(r,>y,,-1,--)r++?strcpy(l[o],l[o-1]+--x),c[o-1]=x,l[o-1][x]=0:0;c[y++]=strlen(l[o]);x=1;}U(){strcat(*L,l[y]);*C=strlen(*L);L(y+1,<r,-1,,++)--r;*l[r]=c[r]=0;}X(b)R(c[y-1],+1)Y(b)R(r,)main(){for(;;){z=i=y;L=l+--z;C=c+z;j=x;!r||y/r&&x>*C?P"end> "):P"%d,%d> ",y,x);scanf("%[^\n]%*c",a)?a[2]*=!!a[1],N(a)?y=Y(i+(i<0|*a=='+')*y),x=X(j+(j<0||strchr(a+1,'+'))*x):0:(*a=D(),scanf("%*c"));switch(*a){A'e':y=r;x=c[r-1]+1;B;A'b':y=1;x=1;B;A'L':for(o=y-4;++o<y+2;)o<0^o<r&&P"%c%s\n",o^z?' ' :'>',l[o]);for(o=x+1;--o;)P" ");P"^\n");B;A'l':puts(*L);B;A'p':i=1;j=0;N(a+2);for(o=Y(i)-1;o<Y(j);++o)puts(l[o]);B;A'A':y=r++;strcpy(l[y],a+2);x=c[y]=strlen(a+2);++x;++y;B;A'i':D();--y;x=X(0);A'r':strcpy(*L+x-1,a+2);*C=strlen(*L);x=1;++y>r&&++r;B;A'I':o=strlen(a+2);memmove(*L+x+o-1,*L+x-1,*C-x+1);*C+=o;memcpy(*L+x-1,a+2,o);x+=o;B;A'd':**L?**L=*C=0,x=1:U();y=y>r?r:y;B;A'j':y<r&&U();}}}
>
> ```

## Limitation

This breaks definitions such as

```
#define A (x)

```

by removing the space that separates the name from expansion, giving

```
#define A(x)

```

with an entirely different meaning. This case is absent from the test sets, so I'm not going to address it.

I suspect I might be able to produce a shorter version with a multi-pass in-place conversion - I might try that next week.

# Answer
> 2 votes
# Perl 5, ~~250+3 (-00n)~~, 167+1 (-p) bytes

```
$_.=<>while s/\\
//;s,(//.*)|(("|')(\\.|.)*?\3)|/?[^"'/]+,$1|$2?$2:$&=~s@(\S?)\K\s+(?=(.?))@"$1$2"=~/\w\w|\+\+|--|\/\*/&&$"@ger,ge;$d++&&$l+/^#/&&s/^/
/,$l=/^#/m if/./

```

Try it online

# Answer
> 2 votes
# C,  ~~705~~   ~~663~~  640 bytes

*Thanks to @Zacharý for golfing 40 bytes and thanks to @Nahuel Fouilleul for golfing 23 bytes!*

```
#define A(x)(x>47&x<58|x>64&x<91|x>96&x<123)
#define K if(*C==47&(C[1]==47|p==47)){if(p==47)--G;for(c=1;c;*C++-92||c++)*C-10||--c;if(d)p=*G++=10,--d;
#define D if(!d&*C==35){d=1;if(p&p-10)p=*G++=10;}
#define S K}if((A(p)&A(*C))|(p==*C&l==43|p==45)|p==47&*C==42|p==95&(A(*C)|*C==95)|*C==95&(A(p)|p==95))p=*G++=32;}
#define W*C<33|*C==92
#define F{for(;W;C++)
c,d,e,p,l;g(char*C,char*G)F;for(;*C;*C>32&&*C-34&&*C-39&&(p=*G++=*C),*C-34&&*C-39&&C++){l=e=0;if(*C==34)l=34;if(*C==39)l=39;if(l)for(*G++=l,p=*G++=*++C;*C++-l|e%2;e=*(C-1)-92?0:e+1)p=*G++=*C;K}D if(d){if(W)F{*C-92||++d;*C-10||--d;if(!d){p=*G++=10;goto E;}}S}else{if(W)F;S}E:D}*G=0;}

```

Try it online!

# Answer
> 0 votes
# Python 2, ~~479~~ ~~456~~ ~~445~~ ~~434~~ ~~502~~ 497 bytes

```
e=enumerate
import re
u=re.sub
def f(s):
 r=()
 for l in u(r'\\\n','',s).split('\n'):
	s=p=w=0;L=[]
	for i,c in e(l):
	 if(p<1)*'//'==l[i:i+2]:l=l[:i]
	 if c in"'\""and w%2<1:
		if p in(c,0):L+=[l[s:i+1]];s=i+1
		p=[0,c][p<1]
	 w=[0,w+1]['\\'==c]
	r+=L+[l[s:]],
 S=''
 for l in r:s=''.join([u('. .',R,u('. .',R,u('\s+',' ',x))).strip(),x][i%2]for i,x in e(l));S+=['%s','\n%s\n'][s[:1]=='#']%s
 print u('\n\n','\n',S).strip()
def R(m):g=m.group(0);f=g[::2];return[f,g][f.isalnum()or f in'++ -- /*']

```

Try it online!

Edit: Fixed to include `- -`,`+ +`, and `/ *`

---
Tags: code-golf, c
---