let it leave me like a long breath

let it dissipate or fade in the background

(no subject) (Reply)

Profile

xax: purple-orange {11/3 knotwork star, pointed down (Default)
howling howling howling

Nav

  • Recent Entries
  • Archive
  • Reading
  • Tags
  • Memories
  • Profile

Tags

  • art - 2 uses
  • asteroid garden - 4 uses
  • code - 19 uses
  • demos - 1 use
  • dreams - 5 uses
  • ff7 fangame - 23 uses
  • fic prompts - 13 uses
  • gamedev challenge - 82 uses
  • hell game - 76 uses
  • nanowrimo - 11 uses
  • plants - 9 uses
  • process - 52 uses
  • programming - 51 uses
  • screenshots - 5 uses
  • writing log - 83 uses

May 2025

S M T W T F S
    123
45678 910
1112131415 1617
18192021222324
25262728293031
  • xax: purple-orange {11/3 knotwork star, pointed down (Default)
    [personal profile] xax
    Tags:
    • code,
    • gamedev challenge,
    • programming
    posted @ 02:50 pm

    hey i have a math problem i was hoping somebody could solve

    okay so as you may already know i wrote some haskell code for enumerating through values, and that was real neat and useful and generally speaking i accomplished a lot with it.

    now i'm trying to expand it. specifically: the code as written lets you enumerate through values, but in constructing the values any sense of relative position is lost. you can do something like V2 <$> from [1..10] <*> from [1..20] and that will let you enumerate through all 200 values, but if you have an index representing, say, V2 3 7 (index 62 btw) you can't say "i want to see the indices of all values that are one unit adjacent". basically there's no way to inspect a deck.

    SO i had the idea to track mergings of decks. change the data type to

    data Enumerable a = Enumerable
      { count :: Integer
      , segments :: [Integer]
      , selector :: Integer -> a
      }


    and make the applicative instance

    instance Applicative Enumerable where
      pure v = Enumerable 1 [1] $ const v
      (Enumerable c s f) <*> (Enumerable c' s' g) =
        Enumerable (c * c') (s <> ((c *) <$> s')) $ \i -> let
            j = i `mod` c
            k = i `div` c
          in f j $ g k


    so that V2 <$> from [1..10] <*> from [1..20] value would have 'segments' of [1,10], meaning that there are two axes: one that increases/decreases in steps of 1 and one that increases/decreases in steps of 10.

    and so then you can decompose indices into movements along those axes, like so:

    decompose :: Enumerable a -> Integer -> [Integer]
    decompose (Enumerable _ s _) i' = snd $ mapAccumR split i' s
      where
        split :: Integer -> Integer -> (Integer, Integer)
        split i c = (i `mod` c, i `div` c)


    and it will say: okay index 62 there decomposes to [2,6]. and then you can do something like...

    mutate :: Enumerable a -> [Integer] -> [[Integer]]
    mutate e i = tail $ recombine $ zip i mutvals
      where
        mutvals = uncurry spread <$> zip (maxAxes e) i
        spread m c = snd <$> filter fst
          [ (c > 0, c - 1)
          , (c < m, c + 1)
          ]
        recombine [] = [[]]
        recombine ((base,vars):rs) = ((:) <$> pure base <*> recombine rs)
          <> ((:) <$> vars <*> pure (fst <$> rs))
    
    maxAxes :: Enumerable a -> [Integer]
    maxAxes e = decompose e $ count e - 1
    
    mutateI :: Enumerable a -> Integer -> [Integer]
    mutateI e i = construct e <$> mutate e (decompose e i)
    


    to have it spit out all decomposed values that are one unit distant. so then:

    λ> let foo = ((,) <$> from [1..10] <*> from [1..20])
    λ> select foo 62
    Just (3,7)
    λ> mutateI foo 62
    [52,72,61,63]
    λ> select foo <$> mutateI foo 62
    [Just (3,6),Just (3,8),Just (2,7),Just (4,7)]


    and now you can navigate around within a enumerable deck. very neat. i'm currently using this to put together some really basic plant mutation/crossbreeding code (since you can also crossbreed two indices by decomposing them, and then picking values randomly from the two sets) and it's generally working pretty well.

    the PROBLEM is:

    the original formulation of Enumerable is also an Alternative and a Monoid:

    instance Alternative Enumerable where
      empty = Enumerable 0 $ const (error "no value")
      (Enumerable c v) <|> (Enumerable c' v') =
        Enumerable (c + c') $ \i -> case i - c of
          x | x >= 0 -> v' x
            | otherwise -> v i
    
    instance Monoid (Enumerable a) where
      mempty = empty
      mappend = (<|>)


    BUT: this new formulation would require some additional segment tracking. Applicative is really easy to store because it just creates n-dimensional prisms with totally regular axes. Alternative is a lot trickier, because it would involve... adding offsets? something? the actual lookup math above is really simple, but if i wanted to store that as a segment i'm pretty sure i would need to stop using just lists of integers.

    i've looked at a lot of math and i've tried to mark out the patterns it would make in indexing and i have yet to really figure out what i should do with it. i think the GOAL is to have it treat all choices as adjacent? so like pure 1 <|> pure 2 <|> pure 3 <|> pure 4 would be different from from [1,2,3,4] because the alternative would consider 1 adjacent to all of 2, 3, and 4, whereas the basic enumeration would only consider 1 adjacent to 2. (and then from [1,2] <|> from [3,4] <|> from [5,6] <|> from [7,8] would consider 1 and 2 to be adjacent to each other and to all of 3 5 and 7. ditto 3 & 4 with 1, 5, and 7.)

    it's just uhhhh i am totally failing to see whatever structure i need to see to codify that up, so, if anybody has any thoughts i would like to hear them.

    (spoilers this two-week project is gonna be trying to make something like this.)

    • Previous Entry
    • Add Memory
    • Share This Entry
    • Next Entry
    • Link
    • 0 comments
  • If you don't have an account you can create one now.
    No Subject Icon Selected
    No Subject Icon Selected
    Smiley
    Winking Smiley
    Blushing Smiley
    Shocked Smiley
    Sad Smiley
    Angry Smiley
    Checkmark
    Gold Star
    Envelope
    Shifty Eyes
    Smiling Alien
    Skull and Crossbones
    Sick Face
    Radioactive Symbol
    Cool Smiley
    Lightbulb
    Red Thumbs Down
    Green Thumbs Up
    HTML doesn't work in the subject.
    More info about formatting
     
    Notice: This account is set to log the IP addresses of people who comment anonymously.
    Links will be displayed as unclickable URLs to help prevent spam.
Page generated Jul. 21st, 2025 05:09 am
Powered by Dreamwidth Studios

Style Credit

  • Style: (No Theme) for vertical