Skip to content

Instantly share code, notes, and snippets.

@masyukun
Created July 1, 2025 03:25
Show Gist options
  • Save masyukun/9a14007a5c0696743df27156c83ecf6a to your computer and use it in GitHub Desktop.
Save masyukun/9a14007a5c0696743df27156c83ecf6a to your computer and use it in GitHub Desktop.
Remap the order of data in Google Sheets using a space-filling Hilbert curve
Function name: HILBERT_MAP
Function description: Call the Hilbert function and map it to the data
Argument placeholders: [position, level, edge, source_1d, direction]
Formula definition:
=arrayformula(HLOOKUP(HILBERT(position,level,edge,direction),{COLUMN(source_1d)-index(COLUMN(source_1d),1,1)+1;source_1d},2))
Function name: HILBERT
Function description: Generate Hilbert sequence of specified size
Argument placeholders: [position, level, edge, direction]
Formula definition:
=if(level=1, if(direction="LEFT", { position, HILBERT_MOVE(position,edge,"RIGHT"), HILBERT_MOVE(HILBERT_MOVE(position,edge,"RIGHT"),edge,"DOWN"), HILBERT_MOVE(HILBERT_MOVE(HILBERT_MOVE(position,edge,"RIGHT"),edge,"DOWN"), edge,"LEFT") }, if(direction="RIGHT", { position, HILBERT_MOVE(position,edge,"LEFT"), HILBERT_MOVE(HILBERT_MOVE(position,edge,"LEFT"),edge,"UP"), HILBERT_MOVE(HILBERT_MOVE(HILBERT_MOVE(position,edge,"LEFT"),edge,"UP"), edge, "RIGHT") }, if(direction="UP", { position, HILBERT_MOVE(position,edge,"DOWN"), HILBERT_MOVE(HILBERT_MOVE(position,edge,"DOWN"),edge,"RIGHT"), HILBERT_MOVE(HILBERT_MOVE(HILBERT_MOVE(position,edge,"DOWN"),edge,"RIGHT"), edge, "UP") }, if(direction="DOWN", { position, HILBERT_MOVE(position,edge,"UP"), HILBERT_MOVE(HILBERT_MOVE(position,edge,"UP"),edge,"LEFT"), HILBERT_MOVE(HILBERT_MOVE(HILBERT_MOVE(position,edge,"UP"),edge,"LEFT"), edge, "DOWN") }, {} ) ) ) ), if(direction="LEFT", { HILBERT(position, level-1, edge, "UP"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "UP"),1,counta(HILBERT(position, level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "LEFT"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "UP"),1,counta(HILBERT(position, level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "LEFT"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "UP"),1,counta(HILBERT(position, level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "LEFT"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "UP"),1,counta(HILBERT(position, level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "LEFT"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "UP"),1,counta(HILBERT(position, level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "LEFT"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "UP"),1,counta(HILBERT(position, level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "LEFT"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "UP"),1,counta(HILBERT(position, level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "LEFT"))), edge, "LEFT"), level-1, edge, "DOWN") }, if(direction="RIGHT", { HILBERT(position, level-1, edge, "DOWN"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "DOWN"),1,counta(HILBERT(position, level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "RIGHT"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "DOWN"),1,counta(HILBERT(position, level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "RIGHT"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "DOWN"),1,counta(HILBERT(position, level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "RIGHT"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "DOWN"),1,counta(HILBERT(position, level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "RIGHT"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "DOWN"),1,counta(HILBERT(position, level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "RIGHT"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "DOWN"),1,counta(HILBERT(position, level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "RIGHT"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "DOWN"),1,counta(HILBERT(position, level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "RIGHT"))), edge, "RIGHT"), level-1, edge, "UP") }, if(direction="UP", { HILBERT(position, level-1, edge, "LEFT"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "LEFT"),1,counta(HILBERT(position, level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "UP"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "LEFT"),1,counta(HILBERT(position, level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "UP"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "LEFT"),1,counta(HILBERT(position, level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "UP"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "LEFT"),1,counta(HILBERT(position, level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "UP"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "LEFT"),1,counta(HILBERT(position, level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "UP"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "LEFT"),1,counta(HILBERT(position, level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "UP"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "LEFT"),1,counta(HILBERT(position, level-1, edge, "LEFT"))), edge, "DOWN"), level-1, edge, "UP"))), edge, "RIGHT"), level-1, edge, "UP"))), edge, "UP"), level-1, edge, "RIGHT") }, if(direction="DOWN", { HILBERT(position, level-1, edge, "RIGHT"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "RIGHT"),1,counta(HILBERT(position, level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "DOWN"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "RIGHT"),1,counta(HILBERT(position, level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "DOWN"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "RIGHT"),1,counta(HILBERT(position, level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "DOWN"), HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "RIGHT"),1,counta(HILBERT(position, level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "DOWN"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "RIGHT"),1,counta(HILBERT(position, level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "DOWN"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "RIGHT"),1,counta(HILBERT(position, level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "DOWN"),1,counta(HILBERT(HILBERT_MOVE(INDEX(HILBERT(position, level-1, edge, "RIGHT"),1,counta(HILBERT(position, level-1, edge, "RIGHT"))), edge, "UP"), level-1, edge, "DOWN"))), edge, "LEFT"), level-1, edge, "DOWN"))), edge, "DOWN"), level-1, edge, "LEFT") }, {} ) ) ) ) )
Function name: HILBERT_MOVE
Function description: Get the next Hilbert curve position for this string position
Argument placeholders: [position, edge_length, direction]
Formula definition:
=SWITCH(direction, "UP", position-edge_length, "DOWN", position+edge_length, "LEFT", position-1, "RIGHT", position+1)
@masyukun
Copy link
Author

masyukun commented Jul 1, 2025

These 3 functions are things you can create in Google Sheets using the Named Function feature. To create them, go to Data --> Named functions --> Add new function.

Invoke the entry point function like this:
=HILBERT_MAP(1,2,4,B6:BM6,"UP")

Where the parameters are:

  • 1 = the starting position (always 1),
  • 3 = the Hilbert level,
  • 4 = the length of the edge of the Hilbert space to fill,
  • B6:BM6 = the data range in Excel to perform the remapping on.,
  • "UP" = the initial orientation of the Hilbert curve

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