跳转到内容

User:ColorfulGalaxy/Programs

此后如竟没有炬火,我便是唯一的光。
CurrentNews留言 | 贡献2025年10月20日 (一) 10:20的版本 (----)

xdi8tools.py

Unfortunately, I still have no idea how to obtain the entire Shidinn dictionary database (including ).

from xdict import dict_xdi8
# dict_xdi8 is a Shidinn dictionary e.g. { '一':'NV','二':'42' }

b1i45=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,(0),0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,44,39,42,22,23,38,26,41,0,0,0,0,0,0,0,
       0,35,27,0,11,34,25,0,14,0,0,0,37,0,15,0,
       0,0,0,0,40,0,43,0,0,36,0,0,0,0,0,0,
       0,31,1,28,17,33,29,19,21,45,5,20,16,3,9,32,
       2,6,13,12,18,30,24,4,7,8,10,0,0,0,0,0,0]+65535*[0]
b1i90000=[(((i-1)%9+1) * (10**((i-1)//9))if i!=0 else 0) for i in b1i45]
xdi8hanzi=list(dict_xdi8.keys())

def b1i45encode(word):
    return ' '.join((str(b1i45[ord(q)]) if len(str(b1i45[ord(q)]))>=2 else '0'+str(b1i45[ord(q)])) for q in word)

def b1i90000sum(word):
    return sum([b1i90000[ord(q)] for q in word])

def translate_into_xdi8(word,sep=''):
    return sep.join((dict_xdi8[q] if (q in xdi8hanzi) else q) for q in word)

Infinite song list tools

These programs might not be run regularly. This is because the input is so large that it might not fit on "Try it online". A seperate offline engine for Python would be needed.

The chart will be placed in User:ColorfulGalaxy/荆哲歌单/可排序表格. (citation needed)

Convert json to python dictionary

Takes Module:Songlist-brief.json as input.

import json
with open("songlist-brief-03547b.json","r",encoding="utf-8") as f:
    data=json.load(f)

with open("songlist_brief_03547b.py","w",encoding="utf-8") as g:
    print('songlist=',data,file=g)

print('done')

Convert python dictionary to wiki chart

New columns added. You can help us expand it.

from songlist_brief_03547b import songlist
import sys
import os.path
from xdi8tools import *

songnumbers=list(songlist['songlist'].keys())

# xdi8aho translation exception
xdi8exlist={
    '0':'He f8 k2 Huo k2 miLh',
    '239':'jbia rA xue',
    '1751':'6li8 ju6 k2 42',
    }
xdi8exlistk=list(xdi8exlist.keys())

def xdi8titleof(num1,sep1=''):
    return (xdi8exlist[num1].replace(' ','') if sep1=='' else xdi8exlist[num1]) if num1 in xdi8exlistk else translate_into_xdi8(songlist['songlist'][songnumbers[p]]['song']['name'],sep=sep1)

timelist={
    '0':'0'
    }
timelistk=list(timelist.keys())

keylist={
    '0':'0'
    }
keylistk=list(keylist.keys())

keymodlist={
    '0':'0'
    }
keymodlistk=list(keymodlist.keys())

titleclasslist={
    '0':1,
'1':6,
'10':6,
'11':2,
'18':5,
'21':6,
'33':6,
'41':5,
'75':1,
'92':3,
'98':6,
'160':5,
'208':6,
'236':6,
'255':5,
'256':6,
'275':5,
'315':6,
'335':3,
'400':5,
'418':6,
'428':6,
'480':5,
'489':3,
'555':6,
'618':5,
'625':'6<ref>Case insensitive</ref>',
'630':3,
'650':6,
'672':5,
'737':6,
'741':5,
'850':4,
'866':6,
'893':'6<ref>This song has two different titles. If you consider the English title, it is in Group 3 instead.</ref>',
'899':6,
'914':6,
'1011':5,
'1046':3,
'1134':6,
'1282':6,
'1315':6,
'1317':6,
'1331':6,
'1521':3,
'1528':6,
'1554':6,
'1582':6,
'1616':6,
'1660':3,
'1672':6,
'1983':3,
'2011':2,
    }
titleclasslistk=list(titleclasslist.keys())

# 30 day song challenge (ColorfulGalaxy's opinion)
# One song may have multiple "days", while not all songs will have a "day".
tdsclist={
'255':'23',
'737':'08',
'810':'08',
    }
tdsclistk=list(tdsclist.keys())


saltdatelist={
'810':'2025-07-18',
'236':'2025-07-26',
'2011':'2025-08-01',
'418':'2025-08-05',
'1521':'2025-08-06',
'625':'2025-08-07',
'672':'2025-08-08',
'1011':'2025-08-09',
'1134':'2025-08-10',
'1983':'2025-08-13',
'275':'2025-08-14',
'33':'2025-08-17',
'1660':'2025-08-22',
'1046':'2025-08-23',
'10':'2025-08-26',
'400':'2025-08-27',
'75':'2025-08-29',
'256':'2025-08-30',
'914':'2025-08-31',
'41':'2025-09-03',
'1315':'2025-09-05',
'1528':'2025-09-07',
'866':'2025-09-08',
'1554':'2025-09-09',
'335':'2025-09-12',
'1282':'2025-09-13',
'737':'2025-09-15',
'1317':'2025-09-20',
'160':'2025-09-21',
'315':'2025-09-24',
'98':'2025-09-26',
'208':'2025-09-27',
'18':'2025-10-02',
'92':'2025-10-04',
'1582':'2025-10-05',
'630':'2025-10-08',
'618':'2025-10-09 (questionable)',
'428':'2025-10-11',
'1616':'2025-10-13',
'255':'2025-10-14',
'741':'2025-10-15',
'480':'2025-10-17',
'489':'2025-10-19',
'1672':'2025-10-20',
    }
saltdatelistk=list(saltdatelist.keys())

# 与之 旋律/和声/节奏/曲风 相近的音游曲目
# Not all songs will be paired with a rhythm game soundtrack
rhythmgamesonglist={
'650':'Komorebi (ADOFAI)',
'899':'Temple Fair (RS)',
'903':'Tropical Tides (RS)',
    }
rhythmgamesonglistk=list(rhythmgamesonglist.keys())

f=open("songlist-wikifile.txt","w",encoding="utf-8")

f.write("\'\'\'Lucas Song List\'\'\', also called the Infinite Song List, is a system organized by Lucas that maps popular songs to integers in a somewhat mathematical manner. \n")
f.write("The current database version is 03547b. The list below may contain errors, mainly because the Shidinn translator (programmed manually by ColorfulGalaxy) is unable to handle homograph.\n\n")

f.write("{| class=\"wikitable sortable\"\n");
f.write("! Number !! Song title !! Singers !! Title in Shidinn !! b1i45 index !! Shidinn numeral sum !! Time signature !! Key signature !! Key modulation (half-steps) !! [http://puzzling.stackexchange.com/questions/106137 Title category] !! Day # in<br>original<br>30-day song<br>challenge !! Salt song guess date !! 与之 旋律/和声/节奏/曲风 相近的音游曲目\n");

for p in range(len(songnumbers)):
    f.write("|-\n")
    f.write("| "+songnumbers[p]+" || ")
    f.write(songlist['songlist'][songnumbers[p]]['song']['name']+" || "+','.join(songlist['songlist'][songnumbers[p]]['song']['singers'])+" || ")
    f.write(xdi8titleof(songnumbers[p],sep1=' ')+" || ")
    f.write(b1i45encode(xdi8titleof(songnumbers[p]))[0:17]+" || ")
    f.write(str(b1i90000sum(xdi8titleof(songnumbers[p])))+" || ")
    f.write((timelist[songnumbers[p]]if songnumbers[p] in timelistk else '')+" || ");
    f.write((keylist[songnumbers[p]]if songnumbers[p] in keylistk else '')+" || ");
    f.write((keymodlist[songnumbers[p]]if songnumbers[p] in keymodlistk else '')+" || ");
    f.write(str(titleclasslist[songnumbers[p]]if songnumbers[p] in titleclasslistk else '')+" || ");
    f.write((tdsclist[songnumbers[p]]if songnumbers[p] in tdsclistk else '')+" || ");
    f.write((saltdatelist[songnumbers[p]]if songnumbers[p] in saltdatelistk else '')+" || ");
    f.write((rhythmgamesonglist[songnumbers[p]]if songnumbers[p] in rhythmgamesonglistk else '')+"\n");
    
    # TODO
f.write("|}")

f.close()

Factorial base calculator

def carry(n:list):
 for i in range(len(n)-1,1,-1):
  n[i-1]+=n[i]//i
  n[i]=n[i]%i
 return n
def add(n1:list,n2:list):
 while len(n1)<len(n2):
  n1.append(0)
 for i in range(len(n2)):
  n1[i]+=n2[i]
 return carry(n1)

pi=[0,0,0]
fa=2
for b in range(3,73,2):
 fa*=(b//2+1)*(b-1)
 add(pi,[0]*b+[fa])
 print(pi)
print()

e=[0,1,0]
for b in range(1,15):
 add(e,[0]*b+[1])
print(e)

Older programs

Chart generator (August 2025 - a new version using custom xdi8tools module should be uploaded)

import sys
import os.path
import pypinyin
import xdi8string # all the characters spaced out translated into shidinn
f=open("wikifile.txt","w",encoding="utf-8")

characters=[chr(i) for i in range(0x4e00,0xa000)]
plaintext=' '.join(chr(n) for n in range(0x4e00,0xa000))
ciphertext=xdi8string.output

b1i45=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,(0),0,0,0,0,0,0,0,0,0,0,0,0,0,0,
       0,44,39,42,22,23,38,26,41,0,0,0,0,0,0,0,
       0,35,27,0,11,34,25,0,14,0,0,0,37,0,15,0,
       0,0,0,0,40,0,43,0,0,36,0,0,0,0,0,0,
       0,31,1,28,17,33,29,19,21,45,5,20,16,3,9,32,
       2,6,13,12,18,30,24,4,7,8,10,0,0,0,0,0,0]
b1i90000=[(((i-1)%9+1) * (10**((i-1)//9))if i!=0 else 0) for i in b1i45]

def b1i45encode(word):
    return ' '.join((str(b1i45[ord(q)]) if len(str(b1i45[ord(q)]))>=2 else '0'+str(b1i45[ord(q)])) for q in word)

def b1i90000sum(word):
    return sum([b1i90000[ord(q)] for q in word])

plain=plaintext.split()
cipher=ciphertext.split()

maxlength=0
maxlench=[]

f.write("Do not simply rely on this chart to translate, as this chart did not handle [[talk:希顶日本语#注意多音字|homograph]] properly. The calculation may be incorrect. If so, please fix it.")

f.write("{| class=\"wikitable sortable\"\n");
f.write("! Character !! Unicode decimal !! Stroke count !! han4 yu3 pin1 yin1 !! xdi8 aho !! [[b1i45密码|b1i45]] !! xdi8 aho letter count !! [[希顶解经|Numeral sum]] !! Stress pattern !! Notes\n")
for p in range(len(plain)):
    if(plain[p]!=cipher[p]):
        f.write("|-\n");
        f.write("| "+plain[p]+" || ")
        f.write(str(ord(plain[p])))
        f.write(" || || ")
        f.write(pypinyin.pinyin(characters[p],style=pypinyin.Style.TONE3,neutral_tone_with_five=True)[0][0])
        f.write(" || "+cipher[p])
        f.write(" || "+b1i45encode(cipher[p]))
        f.write(" || "+str(len(cipher[p])))
        f.write(" || "+str(b1i90000sum(cipher[p])) + "\n")
        if(maxlength<len(cipher[p])):
            maxlench=[p]
            maxlength=len(cipher[p])
        elif(maxlength<=len(cipher[p])):
            maxlench+=[p]
f.write("|}")
print(maxlench,maxlength,len(maxlench))

f.close();