1+ # Text processing utilities
2+ from typing import List
3+
4+ def split_phrase_into_lines (phrase : str , forced_lines : int = None ) -> List [str ]:
5+ """
6+ Split a phrase into multiple lines for better visual display.
7+ """
8+ words = phrase .split ()
9+ n = len (words )
10+
11+ if n <= 3 :
12+ return words
13+
14+ # Helper: total length of a list of words (including spaces between words)
15+ def segment_length (segment ):
16+ return sum (len (word ) for word in segment ) + (len (segment ) - 1 if segment else 0 )
17+
18+ candidates = [] # list of tuples: (number_of_lines, diff, candidate)
19+
20+ # 2-line candidate
21+ best_diff_2 = float ('inf' )
22+ best_seg_2 = None
23+ for i in range (1 , n ):
24+ seg1 = words [:i ]
25+ seg2 = words [i :]
26+ len1 = segment_length (seg1 )
27+ len2 = segment_length (seg2 )
28+ diff = abs (len1 - len2 )
29+ if diff < best_diff_2 :
30+ best_diff_2 = diff
31+ best_seg_2 = [" " .join (seg1 ), " " .join (seg2 )]
32+ if best_seg_2 is not None :
33+ candidates .append ((2 , best_diff_2 , best_seg_2 ))
34+
35+ # 3-line candidate (if at least 4 words)
36+ if n >= 4 :
37+ best_diff_3 = float ('inf' )
38+ best_seg_3 = None
39+ for i in range (1 , n - 1 ):
40+ for j in range (i + 1 , n ):
41+ seg1 = words [:i ]
42+ seg2 = words [i :j ]
43+ seg3 = words [j :]
44+ len1 = segment_length (seg1 )
45+ len2 = segment_length (seg2 )
46+ len3 = segment_length (seg3 )
47+ current_diff = max (len1 , len2 , len3 ) - min (len1 , len2 , len3 )
48+ if current_diff < best_diff_3 :
49+ best_diff_3 = current_diff
50+ best_seg_3 = [" " .join (seg1 ), " " .join (seg2 ), " " .join (seg3 )]
51+ if best_seg_3 is not None :
52+ candidates .append ((3 , best_diff_3 , best_seg_3 ))
53+
54+ # 4-line candidate (if at least 5 words)
55+ if n >= 5 :
56+ best_diff_4 = float ('inf' )
57+ best_seg_4 = None
58+ for i in range (1 , n - 2 ):
59+ for j in range (i + 1 , n - 1 ):
60+ for k in range (j + 1 , n ):
61+ seg1 = words [:i ]
62+ seg2 = words [i :j ]
63+ seg3 = words [j :k ]
64+ seg4 = words [k :]
65+ len1 = segment_length (seg1 )
66+ len2 = segment_length (seg2 )
67+ len3 = segment_length (seg3 )
68+ len4 = segment_length (seg4 )
69+ diff = max (len1 , len2 , len3 , len4 ) - min (len1 , len2 , len3 , len4 )
70+ if diff < best_diff_4 :
71+ best_diff_4 = diff
72+ best_seg_4 = [" " .join (seg1 ), " " .join (seg2 ), " " .join (seg3 ), " " .join (seg4 )]
73+ if best_seg_4 is not None :
74+ candidates .append ((4 , best_diff_4 , best_seg_4 ))
75+
76+ # If a forced number of lines is specified, try to return that candidate first
77+ if forced_lines is not None :
78+ forced_candidates = [cand for cand in candidates if cand [0 ] == forced_lines ]
79+ if forced_candidates :
80+ _ , _ , best_candidate = min (forced_candidates , key = lambda x : x [1 ])
81+ return best_candidate
82+
83+ # Otherwise, choose the candidate with the smallest diff
84+ if candidates :
85+ _ , _ , best_candidate = min (candidates , key = lambda x : x [1 ])
86+ return best_candidate
87+ else :
88+ # fallback (should never happen)
89+ return [" " .join (words )]
0 commit comments