Skip to content

Instantly share code, notes, and snippets.

@s5bug
Created September 9, 2023 10:26
Show Gist options
  • Save s5bug/5cd56655262e33afffe395f0bf0af080 to your computer and use it in GitHub Desktop.
Save s5bug/5cd56655262e33afffe395f0bf0af080 to your computer and use it in GitHub Desktop.
Inclusive Volume Spell (HexCasting)

High-level Immutable Algorithm

val volumeWithin: (Vec3, Vec3) -> List[Vec3] = (a: Vec3, b: Vec3) -> {
  val Vec3(ax, ay, az) = a
  val Vec3(bx, by, bz) = b
  
  val (minX, maxX) =
    if(ax <= bx) (ax, bx)
    else (bx, ax)
  val (minY, maxY) =
    if(ay <= by) (ay, by)
    else (by, ay)
  val (minZ, maxZ) =
    if(az <= bz) (az, bz)
    else (bz, az)
  
  val goI: (Int, List[Vec3]) => List[Vec3] = (i: Int, acci: List[Vec3]) => {
    if(i > maxX) acci
    else {
      val goJ: (Int, List[Vec3]) => List[Vec3] = (j: Int, accj: List[Vec3]) => {
        if(j > maxY) accj
        else {
          val goK: (Int, List[Vec3]) => List[Vec3] = (k: Int, acck: List[Vec3]) => {
            if(k > maxZ) acck
            else goK(k + 1, Vec3(i, j, k) :: acck)
          }
        
          goJ(j + 1, goK(minZ, accj))
        }
      }
    
      goI(i + 1, goJ(minY, acci))
    }
  }
  
  goI(minX, Nil)
}

Reified Closures

def volumeWithin = // a b -- vol
  disintegrate // -- a bx by bz
  4 // -- a bx by bz 4
  fisherman // -- bx by bz a
  disintegrate // -- bx by bz ax ay az
  /*
  I'm faced with `fedcba` on my stack, and would love to swindle it to
  - `cfbead` (373, simple interleave)
  - `fcbead` (61, interleave + swap first two)
  - `cfebad` (363, interleave + swap middle two)
  - `fcebad` (51, interleave + first two + middle two)
  - `cfbeda` (372, interleave + swap last two)
  - `fcbeda` (60, interleave + first two + last two)
  - `cfebda` (362, interleave + middle two + last two)
  - `fcebda` (50, interleave + all swaps)

  What's important to note here:
  - The "default" value is 373
  - Swapping the first two is -312
  - Swapping the middle two is -10
  - Swapping the last two is -1
  */
  373 // -- bx by bz ax ay az 373
  3
  fisherman2 // -- bx by bz ax ay az 373 ax
  7
  fisherman2 // -- bx by bz ax ay az 373 ax bx
  lteq // -- bx by bz ax ay az 373 (ax<=bx)
  0
  -312
  select
  add // -- bx by bz ax ay az [interleave+swapAXBX?]
  2
  fisherman2
  6
  fisherman2 // -- bx by bz ax ay az [interleave+swapAXBX?] ay by
  lteq // -- bx by bz ax ay az [...] (ay<=by)
  0
  -10
  select
  add // -- bx by bz ax ay az [interleave+swapAXBX?+swapAYBY?]
  prospectors // -- bx by bz ax ay az [...] az
  5
  fisherman2 // -- bx by bz ax ay az [...] az bz
  lteq
  0
  -1
  select
  add
  swindle // -- minX maxX minY maxY minZ maxZ
  // goI captures all of these except for minX. I'll pretend I planned that!
  'goI // -- minX maxX minY maxY minZ maxZ 'goI
  dup // -- minX maxX minY maxY minZ maxZ 'goI 'goI
  empty_list // -- minX maxX minY maxY minZ maxZ 'goI 'goI Nil
  /* Lehmer Code:
  0 - maxX   Nil - 7
  1 - minY  'goI - 5
  2 - maxY  maxX - 0
  3 - minZ  minY - 1
  4 - maxZ  maxY - 2
  5 - 'goI  minZ - 3
  6 - 'goI  maxZ - 4
  7 - Nil   'goI - 6
  
  [7]5 0 1 2 3 4 6
   7[5]0 1 2 3 4 6
   7 5[0]1 2 3 4 5
   7 5 0[0]1 2 3 4
   7 5 0 0[0]1 2 3
   7 5 0 0 0[0]1 2
   7 5 0 0 0 0[0]1
   7 5 0 0 0 0 0[0]
   
  (7! * 7) + (6! * 5) = 38880
  
  38880 = 108 * 360, both drawable literally
  */
  108
  360
  mult
  swindle
  hermes

def goI = // i acci {'goI maxX minY maxY minZ maxZ}-- list
  // pull maxX and i to the front
  /*
  0 1 2 3 4 5 6 7
  
  1 2 4 5 6 7 0 3
  1 1 3 4 5 6 0 2
  1 1 2 3 4 5 0 1
  1 1 2 2 3 4 0 1
  1 1 2 2 2 3 0 1
  1 1 2 2 2 2 0 1
  1 1 2 2 2 2 0 1
  1 1 2 2 2 2 0 0
  (7! * 1) + (6! * 1) + (5! * 2) + (4! * 2) + (3! * 2) + (2! * 2) = 6064
  
  6064 can be directly drawn
  */
  6064
  swindle // -- acci 'goI minY maxY minZ maxZ i maxX
  dup2 // -- acci 'goI minY maxY minZ maxZ i maxX i maxX
  gt // -- acci 'goI minY maxY minZ maxZ i maxX (i>maxX)
  {
    vvvvvvv // -- acci
  }
  {
    swap // -- acci 'goI minY maxY minZ maxZ maxX i
    dup // -- acci 'goI minY maxY minZ maxZ maxX i i
    1
    add // -- acci 'goI minY maxY minZ maxZ maxX i (i+1)
    // desired stack for goJ call: minY acci* 'goJ maxY minZ maxZ i 'goJ
    // many variables are duplicated = we cannot swindle
    6
    fisherman2 // -- acci 'goI minY maxY minZ maxZ maxX i (i+1) minY
    10
    fisherman // -- 'goI minY maxY minZ maxZ maxX i (i+1) minY acci
    'goJ // -- 'goI minY maxY minZ maxZ maxX i (i+1) minY acci 'goJ
    8
    fisherman2 // -- 'goI minY maxY minZ maxZ maxX i (i+1) minY acci 'goJ maxY
    8
    fisherman2 // -- 'goI minY maxY minZ maxZ maxX i (i+1) minY acci 'goJ maxY minZ
    8
    fisherman2 // -- 'goI minY maxY minZ maxZ maxX i (i+1) minY acci 'goJ maxY minZ maxZ
    8
    fisherman // -- 'goI minY maxY minZ maxZ maxX (i+1) minY acci 'goJ maxY minZ maxZ i
    4
    fisherman2
    hermes // -- 'goI minY maxY minZ maxZ maxX (i+1) goJ(minY, acci)
    /*
    0 1 2 3 4 5 6 7
    
    6 7 0 5 1 2 3 4
    6 6 0 5 1 2 3 4
    6 6 0 5 1 2 3 4
    6 6 0 4 0 1 2 3
    ...
    6 6 0 4 0 0 0 0
    
    (7! * 6) + (6! * 6) + (4! * 4) = 34656 = 152 * 228
    */
    152
    228
    mult
    swindle // --  (i+1) goJ(minY, acci) 'goI maxX minY maxY minZ maxZ
    5
    fisherman2
    hermes
  }
  select
  hermes

def goJ = // j accj {'goJ maxY minZ maxZ i}-- list
  // pull j, maxY to the front
  /*
  0 1 2 3 4 5 6
  
  1 2 4 5 6 0 3
  1 1 3 4 5 0 2
  1 1 2 3 4 0 1
  1 1 2 2 3 0 1
  1 1 2 2 2 0 1
  1 1 2 2 2 0 1
  1 1 2 2 2 0 0
  
  (6! * 1) + (5! * 1) + (4! * 2) + (3! * 2) + (2! * 2) = 904
  */
  904
  swindle // -- accj 'goJ minZ maxZ i j maxY
  dup2 // -- accj 'goJ minZ maxZ i j maxY j maxY
  gt // -- accj 'goJ minZ maxZ i j maxY (j>maxY)
  {
    vvvvvv // -- accj
  }
  {
    swap
    dup
    1
    add // -- accj 'goJ minZ maxZ i maxY j (j+1)
    // desired stack for goK call: minZ accj* 'goK maxZ i j 'goK
    5
    fisherman2 // -- accj 'goJ minZ maxZ i maxY j (j+1) minZ
    9
    fisherman // -- 'goJ minZ maxZ i maxY j (j+1) minZ accj
    'goK // -- 'goJ minZ maxZ i maxY j (j+1) minZ accj 'goK
    7
    fisherman2 // -- 'goJ minZ maxZ i maxY j (j+1) minZ accj 'goK maxZ
    7
    fisherman2 // -- 'goJ minZ maxZ i maxY j (j+1) minZ accj 'goK maxZ i
    7
    fisherman // -- 'goJ minZ maxZ i maxY (j+1) minZ accj 'goK maxZ i j
    3
    fisherman2 // -- 'goJ minZ maxZ i maxY (j+1) minZ accj 'goK maxZ i j 'goK
    hermes // -- 'goJ minZ maxZ i maxY (j+1) goK(minZ, accj)
    // we can't combine the swindles due to our inability to push goK down the stack in 0.10.3
    // we could possibly combine both the 'goJ duplication and 'goK duplication into one dioscuri gambit
    // but the resulting swindle numbers might be too large as to require two extra ops, negating the benefit
    /*
    0 1 2 3 4 5 6
    
    5 6 0 4 1 2 3
    5 5 0 4 1 2 3
    5 5 0 4 1 2 3
    5 5 0 3 0 1 2
    5 5 0 3 0 1 2
    5 5 0 3 0 0 1
    5 5 0 3 0 0 0
    
    (6! * 5) + (5! * 5) + (3! * 3) = 4218
    */
    4218
    swindle // -- (j+1) goK(minZ, accj) 'goJ maxY minZ maxZ i
    4
    fisherman2
    hermes
  }
  select
  hermes

def goK = // k acck {'goK maxZ i j}-- list
  dup2 // -- k acck 'goK maxZ i j i j
  /*
  0 1 2 3 4 5 6 7
  
  1 2 4 5 6 7 0 3
  1 1 3 4 5 6 0 2
  1 1 2 3 4 5 0 1
  1 1 2 2 3 4 0 1
  1 1 2 2 2 3 0 1
  1 1 2 2 2 2 0 1
  1 1 2 2 2 2 0 0
  
  (7! * 1) + (6! * 1) + (5! * 2) + (4! * 2) + (3! * 2) + (2! * 2) = 6064
  */
  6304
  swindle // -- acck 'goK i j i j k maxZ
  dup2
  gt // -- acck 'goK i j i j k maxZ (k>maxZ)
  {
    vvvvvvv
  }
  {
    swap // -- acck 'goK i j i j maxZ k
    dup
    1
    add // -- acck 'goK i j i j maxZ k (k+1)
    // we want (k+1) 'goK maxZ i j acck i j k
    /*
    0 1 2 3 4 5 6 7 8
    
    8 1 6 2 3 0 4 5 7
    8 1 6 2 3 0 4 5 7
    8 1 5 1 2 0 3 4 6
    8 1 5 1 2 0 3 4 5
    8 1 5 1 1 0 2 3 4
    8 1 5 1 1 0 1 2 3
    ...
    8 1 5 1 1 0 0 0 0
    
    (8! * 8) + (7! * 1) + (6! * 5) + (5! * 1) + (4! * 1) = 331344 = 708 * 468
    */
    708
    468
    mult
    swindle // -- (k+1) 'goK maxZ i j acck i j k
    exalt // -- (k+1) 'goK maxZ i j acck <i, j, k>
    integrate // -- (k+1) 'goK maxZ i j [...acck, <i, j, k>]
    /*
    0 1 2 3 4
    
    4 0 1 2 3
    */
    96
    swindle // -- (k+1) [...acck, <i, j, k>] 'goK maxZ i j
    3
    fisherman2
    hermes
  }
  select
  hermes

Hex Pattern

Vector Disintegration
Numerical Reflection: 4
Fisherman's Gambit
Vector Disintegration
Numerical Reflection: 373
Numerical Reflection: 3
Fisherman's Gambit II
Numerical Reflection: 7
Fisherman's Gambit II
Minimus Distillation II
Numerical Reflection: 0
Numerical Reflection: -312
Augur's Exaltation
Additive Distillation
Numerical Reflection: 2
Fisherman's Gambit II
Numerical Reflection: 6
Fisherman's Gambit II
Minimus Distillation II
Numerical Reflection: 0
Numerical Reflection: -10
Augur's Exaltation
Additive Distillation
Prospector's Gambit
Numerical Reflection: 5
Fisherman's Gambit II
Minimus Distillation II
Numerical Reflection: 0
Numerical Reflection: -1
Augur's Exaltation
Additive Distillation
Swindler's Gambit
{
    Numerical Reflection: 6064
    Swindler's Gambit
    Dioscuri Gambit
    Maximus Distillation
    {
        Bookkeeper's Gambit: vvvvvvv
    }
    {
        Jester's Gambit
        Gemini Decomposition
        Numerical Reflection: 1
        Additive Distillation
        Numerical Reflection: 6
        Fisherman's Gambit II
        Numerical Reflection: 10
        Fisherman's Gambit
        {
            Numerical Reflection: 904
            Swindler's Gambit
            Dioscuri Gambit
            Maximus Distillation
            {
                Bookkeeper's Gambit: vvvvvv
            }
            {
                Jester's Gambit
                Gemini Decomposition
                Numerical Reflection: 1
                Additive Distillation
                Numerical Reflection: 5
                Fisherman's Gambit II
                Numerical Reflection: 9
                Fisherman's Gambit
                {
                    Dioscuri Gambit
                    Numerical Reflection: 6064
                    Swindler's Gambit
                    Dioscuri Gambit
                    Maximus Distillation
                    {
                        Bookkeeper's Gambit: vvvvvvv
                    }
                    {
                        Jester's Gambit
                        Gemini Decomposition
                        Numerical Reflection: 1
                        Additive Distillation
                        Numerical Reflection: 708
                        Numerical Reflection: 468
                        Multiplicative Distillation
                        Swindler's Gambit
                        Vector Exaltation
                        Integration Distillation
                        Numerical Reflection: 96
                        Swindler's Gambit
                        Numerical Reflection: 3
                        Fisherman's Gambit II
                        Hermes' Gambit
                    }
                    Augur's Exaltation
                    Hermes' Gambit
                }
                Numerical Reflection: 7
                Fisherman's Gambit II
                Numerical Reflection: 7
                Fisherman's Gambit II
                Numerical Reflection: 7
                Fisherman's Gambit
                Numerical Reflection: 3
                Fisherman's Gambit II
                Hermes' Gambit
                Numerical Reflection: 4218
                Swindler's Gambit
                Numerical Reflection: 4
                Fisherman's Gambit II
                Hermes' Gambit
            }
            Augur's Exaltation
            Hermes' Gambit
        }
        Numerical Reflection: 8
        Fisherman's Gambit II
        Numerical Reflection: 8
        Fisherman's Gambit II
        Numerical Reflection: 8
        Fisherman's Gambit II
        Numerical Reflection: 8
        Fisherman's Gambit
        Numerical Reflection: 4
        Fisherman's Gambit II
        Hermes' Gambit
        Numerical Reflection: 152
        Numerical Reflection: 228
        Multiplicative Distillation
        Swindler's Gambit
        Numerical Reflection: 5
        Fisherman's Gambit II
        Hermes' Gambit
    }
    Augur's Exaltation
    Hermes' Gambit
}
Gemini Decomposition
Vacant Reflection
Numerical Reflection: 108
Numerical Reflection: 360
Multiplicative Distillation
Swindler's Gambit
Hermes' Gambit

Requires two Vec3s on the stack beforehand.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment