leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit d3ea88cbdf36833f773e26694de6a1c71d501e47
parent 45170406deedd920af6ebe88b0e309f255d52c37
Author: Jack Sangdahl <jack@pngu.org>
Date:   Tue,  4 Nov 2025 20:18:50 -0700

756. pyramid transition matrix

Diffstat:
Apyramid_transition_matrix.c | 134+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apyramid_transition_matrix.py | 48++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 182 insertions(+), 0 deletions(-)

diff --git a/pyramid_transition_matrix.c b/pyramid_transition_matrix.c @@ -0,0 +1,134 @@ +// 756. Pyramid Transition Matrix +#include "leetcode.h" + +/* + * you are stacking blocks to form a pyramid. each block has a colour which is + * represented by a single letter. each row of blocks contains one less block + * than the row beneat it and is centered on top. to make the pyramid + * aesthetically pleasing, there are only specific triangular patterns that are + * allowed. a triangular pattern consists of a single block stacked on top of + * two blocks. the patterns are given as a list of three letter strings + * 'allowed', where the first two characters of a pattern represent the third + * character is the top block. you start with a bottom row of blocks 'bottom', + * given as a string, that you must use as the base of the pyramid. given + * 'bottom' and 'allowed', return 'true' if you can build the pyramid all the + * way to the top such that every triangular pattern in the pyramid is in + * 'allowed', or false otherwise. + */ + +struct map_ent { + char key[3]; + char *vals; + int cnt; + int capacity; +}; + +struct hashmap { + struct map_ent *entries; + int size; + int capacity; +}; + +struct hashmap *hashmap_init(int capacity) { + struct hashmap *obj = (struct hashmap *)malloc(sizeof(struct hashmap)); + obj->entries = (struct map_ent *)calloc(capacity, sizeof(struct map_ent)); + obj->size = 0; + obj->capacity = capacity; + return obj; +} + +void hashmap_free(struct hashmap *obj) { + for (int i = 0; i < obj->size; i++) + if (obj->entries[i].vals) + free(obj->entries[i].vals); + free(obj->entries); + free(obj); +} + +void hashmap_push(struct hashmap *obj, const char *key, char val) { + for (int i = 0; i < obj->size; i++) + if (!strcmp(obj->entries[i].key, key)) { + if (obj->entries[i].cnt >= obj->entries[i].capacity) { + obj->entries[i].capacity = + !obj->entries[i].capacity ? 4 : obj->entries[i].capacity * 2; + obj->entries[i].vals = (char *)realloc( + obj->entries[i].vals, obj->entries[i].capacity * sizeof(char)); + } + obj->entries[i].vals[obj->entries[i].cnt++] = val; + return; + } + if (obj->size >= obj->capacity) { + obj->capacity *= 2; + obj->entries = (struct map_ent *)realloc( + obj->entries, obj->capacity * sizeof(struct map_ent)); + } + struct map_ent *entry = &obj->entries[obj->size]; + strcpy(entry->key, key); + entry->vals = NULL; + entry->cnt = 0; + entry->capacity = 0; + if (!entry->capacity) { + entry->capacity = 4; + entry->vals = (char *)malloc(entry->capacity * sizeof(char)); + } + entry->vals[entry->cnt++] = val; + obj->size++; +} + +char *hashmap_get(struct hashmap *obj, const char *key, int *cnt) { + for (int i = 0; i < obj->size; i++) + if (!strcmp(obj->entries[i].key, key)) { + *cnt = obj->entries[i].cnt; + return obj->entries[i].vals; + } + *cnt = 0; + return NULL; +} + +bool helper(char *bottom, struct hashmap *m, int start, char *next, int n) { + if (strlen(bottom) == 1) + return true; + if (start == (int)strlen(bottom) - 1) { + next[n] = '\0'; + return helper(next, m, 0, (char *)malloc(strlen(next) + 1), 0); + } + char key[3]; + key[0] = bottom[start]; + key[1] = bottom[start + 1]; + key[2] = '\0'; + int cnt; + char *vals = hashmap_get(m, key, &cnt); + if (!vals) + return false; + for (int i = 0; i < cnt; i++) { + next[n] = vals[i]; + if (helper(bottom, m, start + 1, next, n + 1)) + return true; + } + return false; +} + +bool pyramidTransition(char *bottom, char **allowed, int allowedSize) { + struct hashmap *m = hashmap_init(100); + for (int i = 0; i < allowedSize; i++) { + char key[3]; + key[0] = allowed[i][0]; + key[1] = allowed[i][1]; + key[2] = '\0'; + char val = allowed[i][2]; + hashmap_push(m, key, val); + } + int n = strlen(bottom); + char *next = (char *)malloc(n); + bool ans = helper(bottom, m, 0, next, 0); + free(next); + hashmap_free(m); + return ans; +} + +int main() { + char *b1 = "BCD", *a1[] = {"BCC", "CDE", "CEA", "FFF"}; + char *b2 = "AAAA", *a2[] = {"AAB", "AAC", "BCD", "BBE", "DEF"}; + printf("%d\n", pyramidTransition(b1, a1, ARRAY_SIZE(a1))); // expect: 1 + printf("%d\n", pyramidTransition(b2, a2, ARRAY_SIZE(a2))); // expect: 0 +} diff --git a/pyramid_transition_matrix.py b/pyramid_transition_matrix.py @@ -0,0 +1,48 @@ +# 756. Pyramid Transition Matrix +from collections import defaultdict +from itertools import product + +""" +you are stacking blocks to form a pyramid. each block has a colour which is +represented by a single letter. each row of blocks contains one less block +than the row beneat it and is centered on top. to make the pyramid +aesthetically pleasing, there are only specific triangular patterns that are +allowed. a triangular pattern consists of a single block stacked on top of +two blocks. the patterns are given as a list of three letter strings +'allowed', where the first two characters of a pattern represent the third +character is the top block. you start with a bottom row of blocks 'bottom', +given as a string, that you must use as the base of the pyramid. given +'bottom' and 'allowed', return 'true' if you can build the pyramid all the +way to the top such that every triangular pattern in the pyramid is in +'allowed', or false otherwise. +""" + + +class Solution(object): + def pyramidTransition(self, bottom, allowed): + """ + :type bottom: str + :type allowed: List[str] + :rtype: bool + """ + f = defaultdict(lambda: defaultdict(list)) + for a, b, c in allowed: + f[a][b].append(c) + + def helper(bottom): + return len(bottom) == 1 or any( + helper(i) + for i in product(*(f[a][b] for a, b in zip(bottom, bottom[1:]))) + ) + + return helper(bottom) + + +if __name__ == "__main__": + obj = Solution() + print(obj.pyramidTransition(bottom="BCD", allowed=["BCC", "CDE", "CEA", "FFF"])) + print( + obj.pyramidTransition( + bottom="AAAA", allowed=["AAB", "AAC", "BCD", "BBE", "DEF"] + ) + )