Files
kdp_generator/__pycache__/generator.cpython-313.pyc
T

127 lines
17 KiB
Plaintext
Raw Normal View History

2026-03-24 19:36:04 +02:00
ó
áÊÂij6ãóB•SrSSKrSSKrSSKJr SSKJrJrJrJ r J
r
J r \R"\
5r"SS5rSrS\\ S \S
\4S jrSS \\ S \S
\\R(S
\\4SjjrSS \\ S\S\S \S\\S\S\S
\\4SjjrS\S
\4Sjrg)a!Crossword grid generation algorithm.
Uses a greedy placement strategy with two passes:
1. Sort words longest-first (harder to place, so do them early).
2. Place the first word horizontally in the centre of the grid.
3. For each remaining word, find all positions where it intersects an
already-placed word at a shared letter, score them, and pick the best.
4. Run a second pass for words that failed the first time (the grid has
grown, so new opportunities may exist).
5. Number the cells in reading order and build the Crossword object.
éN)ÚOptional)ÚCellÚ CrosswordÚ DirectionÚ NumberedClueÚ
PlacedWordÚWordCluec óþ•\rSrSrSrS\4SjrS\S\S\\4Sjr S\S\S\
4S jr S\S\S\
4S
jr S \S \S\S\S
\
SS4 SjrS \S\S\S
\
S\
4
SjrS \S\S\S
\
S\4
SjrS \S\\\\\
44SjrS\4SjrSrg)Ú _GridBuilderézØSparse, mutable grid used during crossword construction.
Internally stores letters in a dict keyed by (row, col) so we never
worry about array resizing. Converts to a dense Cell grid only when
`build()` is called.
Úsizecó:•Xl0Ul0Ul/Ulg©N)r
Ú_lettersÚ_dirsÚplaced)Úselfr
s ÚN/Users/mihai.stefanescu/Projects/personal/crossword-kdp-generator/generator.pyÚ__init__Ú_GridBuilder.__init__s€ØŒ Ø46ˆŒ
Ø<>ˆŒ
Ø(*ˆ� óÚrowÚcolÚreturncó:•URRX45$r)rÚget©rrrs rrÚ_GridBuilder.get&s€Ø�}‰}× Ñ  # Ó,Ð,rcó"•X4UR;$r)rrs rÚ is_occupiedÚ_GridBuilder.is_occupied)s€Øˆz˜TŸ]™]Ñ*Ð*rcóŒ•SUs=:*=(a UR:Os =(a SUs=:*=(a UR:$s $©Nr)r
rs rÚ in_boundsÚ_GridBuilder.in_bounds,s5€Ø�C×#Ó#˜$Ÿ)™)Ô#×<¨¨S×(<Ó(<°4·9±9Ñ(<Ð<Ñ(<Ð<rÚwordÚclueÚ directionNcó&•[XX4US9nURRU5 [UR 55HNunup‰XUR
X‰4'UR RX‰4[55RU5 MP g)N©r&r'rrr()
rrÚappendÚ enumerateÚcellsrrÚ
setdefaultÚsetÚadd)
rr&r'rrr(ÚpwÚiÚrÚcs
rÚplaceÚ_GridBuilder.place1su€ä
˜T°#Ø"+ñ-ˆà � ‰ ×ј2ÔÜ" 2§8¡8£:Ö.‰IˆA‰v�Ø$(¡GˆD�M‰M˜1˜&Ñ !Ø �J‰J× !Ñ ! 1 &¬#«%Ó 0× 4Ñ 4°YÖ ?ò/rcóæ•[U5nU[R:XGa)X5-S-
nUS:d$US:dX`R:¼dX R:¼agUR X#S-
5(agUR X&S-5(agSn[ U5H˜nX8-n UR
X)5n
U
bGX¡U:wa g[RURR
X)4[55;a gSnMbUR US-
U 5(dUR US-U 5(dM˜ g U=(d UR(+$X%-S-
n US:d$US:dX°R:¼dX0R:¼agUR US-
U5(agUR U S-U5(agSn[ U5H–nX(-n UR
XÃ5n
U
bGX¡U:wa g[RURR
XÃ4[55;a gSnMbUR XÃS-
5(dUR XÃS-5(dM– g U=(d UR(+$)z:Return True if *word* can legally be placed at (row, col).érFT) ÚlenrÚACROSSr
r Úrangerrr/rÚDOWN)
rr&rrr(ÚlengthÚend_colÚ has_crossr2r4ÚexistingÚend_rowr3s
rÚis_validÚ_GridBuilder.is_valid<s+€ô�T“ˆà œ ×(Ñ(Ô (Ø‘l QÑ&ˆGØ�Q‹w˜# ›' W· ± Ó%9¸SÇIÁIÓ=MØð×Ñ ¨1¡W×-Ñ-ØØ×Ñ ¨q¡[×1Ñ1ØàˆIܘ6–]�Ø‘G�ØŸ8™8 CÓ+�ØÑ'ب¡7Ó*Ù$ä ×'Ñ'¨4¯:©:¯>©>¸3¸(ÄCÃEÓ+JÓJÙ$Ø $’Ið×'Ñ'¨¨a©°×3Ñ3°t×7GÑ7GÈÈaÉÐQR×7SÓ7SÙ$ñ#ð×/ D§K¡K¤Ð /ð‘l QÑ&ˆGØ�Q‹w˜# ›' W· ± Ó%9¸SÇIÁIÓ=MØà×Ñ  a¡¨×-Ñ-ØØ×Ñ ¨!¡ ¨S×1Ñ1ØàˆIܘ6–]�Ø‘G�ØŸ8™8 AÓ+�ØÑ'ب¡7Ó*Ù$Ü —~‘~¨¯©¯©¸¸Ä#Ã%Ó)HÓHÙ$Ø $’Ià×'Ñ'¨°©7×3Ñ3°t×7GÑ7GÈÐQRÉ7×7SÓ7SÙ$ñ#ð×/ D§K¡K¤Ð /rcóà•Sn[U5nU[R:Xa3[U5H#nUR X#U-5(dMUS-
nM% O2[U5H#nUR X'-U5(dMUS-
nM% UR
S- nU[R:Xa[
U5X6S- -p©OX&S- -[
U5p©U[X˜-
5[X¨-
5-S--nU$)u-Score a valid placement — higher is better.gg$@g@gà?)r9rr:r;r r
ÚfloatÚabs) rr&rrr(Úsr=r2ÚcentreÚmid_rÚmid_cs rÚscoreÚ_GridBuilder.scorezsâ€ð
ˆÜ�T“ˆà œ ×(Ñ(Ó (ܘ6–]�Ø×#Ñ# C¨q©×1Ó1ؘ‘I’Aò#ô˜6–]�Ø×#Ñ# C¡G¨S×1Ó1ؘ‘I’Añ#ð
—‘˜S‘ˆØ œ ×(Ñ(Ó (Ü  ›: s°c©\Ñ'9‘5à¨#¡Ñ-¬u°S«z�5Ø Œc�%‘.Ó!¤C¨©Ó$7Ñ7¸3Ñ
>Ñ>ˆàˆrc ó•Sn[S5nURHín[U5HÛupV[UR5H½upxXh:waM UR[
R :Xa.URU-
URU-[
Rpºn O-URU-URU-
[
R pºn URXX«5(dMžURXX«5n XÃ:”dM·U nXšU 4nM¿ MÝ Mï U$)z<Find the highest-scoring valid position for *word*, or None.Nz-inf) rErr,r&r(rr:rrr<rBrK)
rr&Úbest_posÚ
best_scorer1r2Úch_newÚjÚch_oldÚnrÚncÚndÚscs
rÚ find_bestÚ_GridBuilder.find_best•sÛ€à9=ˆÜ˜6“]ˆ
à—+”+ˆBÜ& tž_‘ �Ü!*¨2¯7©7Ö!3‘I�AØÓ'Ù à—|‘|¤y×'7Ñ'7Ó7Ø%'§V¡V¨a¡Z°·±¸!±¼Y¿^¹^ ˜ à%'§V¡V¨a¡Z°·±¸!±¼Y×=MÑ=M ˜à—}‘} T¨r×6Ó6Ø!ŸZ™Z¨°"Ó9˜Ø�?Ø)+˜JØ(*° |šHó"4ó-ñð"ˆrc óH•UR(d [//SSS9$[SUR55n[ SUR55n[SUR55n[ SUR55nX!-
S-nXC-
S-nURVs/sHHn[ UR URURU-
URU-
URS9PMJ nn[U5V s/sH'n [U5V s/sH
n [5PM sn PM) n
n UHAn[UR55H!un upÍUR U X¬U
lM# MC 0nUH:nUR!URUR4/5R#U5 M< /n/nSn[U5H±n [U5HŸn
XÍ4U;aM UX¬U
lXìU
4HxnUUl['UURUR UR5nUR[(R*:XaUR#U5 MgUR#U5 Mz US-
nM¡ M³ [U
UUUUUS 9$s snfs sn fs sn f)
z;Trim to bounding box, number cells, and return a Crossword.r)ÚgridÚ placed_wordsÚwidthÚheightc3ó*# •UH upUv• M g7fr©©Ú.0r3Ú_s rÚ <genexpr>Ú%_GridBuilder.build.<locals>.<genexpr>´óé€Ð0¢-™$˜!•A¢-ùó‚c3ó*# •UH upUv• M g7frr_r`s rrcrdµrerfc3ó*# •UH upUv• M g7frr_©rarbr4s rrcrdrerfc3ó*# •UH upUv• M g7frr_ris rrcrd·rerfr8r*)rZr[Ú across_cluesÚ
down_cluesr\r])rrÚminrÚmaxrr&r'rrr(r;rr,r-Úletterr.r+Únumberrrr:)rÚmin_rÚmax_rÚmin_cÚmax_cr]r\r1ÚshiftedrbrZr2r3r4ÚstartsrkrlÚnumrTs rÚbuildÚ_GridBuilder.build¯sl€à�{�{Ü "°2¸QÀqÑIÐ IäÑ0 $§-¢-Ó0Ó0ˆÜÑ0 $§-¢-Ó0Ó0ˆÜÑ0 $§-¢-Ó0Ó0ˆÜÑ0 $§-¢-Ó0Ó0ˆØ‘ Ñ"ˆØ‘
 Ñ!ˆð—k’kó

ò "�ô
Ø—W‘W 2§7¡7Ø—F‘F˜U‘N¨¯©°©ØŸ,™,ô
ñ
"ð
ð
ô5:¸&´Mó"
Ú4A¨qœU 5œ\Ó *š\˜ŒTŽV™\Ô *±Mð
ð"
óˆBÜ& r§x¡x£zÖ2‘ �‘6�AØ$&§G¡G¨A¡J�‘˜‘
Ö!ó3ñð
;=ˆÛˆBØ × Ñ ˜rŸv™v r§v¡vÐ.°Ó 3× :Ñ :¸2Ö >ñð,.ˆ Ø)+ˆ
؈ä�v–ˆAܘ5–\�Ø�6 Ó'ÙØ$'�‘˜‘
Ô!Ø  Q œ.�BØ #�B”IÜ% c¨2¯7©7°B·G±G¸R¿\¹\ÓJ�BØ—|‘|¤y×'7Ñ'7Ó7Ø$×+Ñ+¨BÖ/à"×)Ñ)¨"Ö-ñ
)ð�q‘’ó"ñôØØ Ø%Ø!ØØñ

ð
ùòQ
ùò
+ùò"
sÂ*AJÄJÄJ
Ä/JÊJ)rrrr
)Ú__name__Ú
__module__Ú __qualname__Ú__firstlineno__Ú__doc__ÚintrrÚstrrÚboolr r$rr5rBrErKÚtuplerWrrxÚ__static_attributes__r_rrr r s"†ñð+˜Sô+ð-�sð- ð-¨°#©ô-ð+˜sð+¨ð+°ô+ð=˜Sð= sð=¨tô=ð
@˜#ð@ Sð@¨sð@¸ð@Ø"ð@Ø'+ô@ð:0˜Sð:0 sð:0°ð:0Ø%ð:0Ø*.ô:0ð|˜#ð Cð¨cðØ"ðØ',ôð6˜cð h¨u°S¸#¸yÐ5HÑ/IÑ&Jôð4<