Skip to content

Instantly share code, notes, and snippets.

@andy0130tw
Created July 24, 2024 19:23
Show Gist options
  • Save andy0130tw/5b97ec5eced8a11816b44e7b4bcf7eb2 to your computer and use it in GitHub Desktop.
Save andy0130tw/5b97ec5eced8a11816b44e7b4bcf7eb2 to your computer and use it in GitHub Desktop.
Did I abuse generators 🫠
function byCallbacks(s0, inp) {
if (inp == null) {
let s = s0
if (s0.integerPart === '') {
s = { ...s0, integerPart: '0' }
}
return s.integerPart + (s.decimalPart ? `.${s.decimalPart}` : '')
} if (s0.readingIntegerPart) {
if (inp === '.') {
return { ...s0, readingIntegerPart: false }
} else if (inp === '0' && s0.integerPart === '') {
return s0
} else {
const integerPart = s0.integerPart + inp
return { ...s0, integerPart }
}
} else {
if (inp === '0') {
const zeroCount = s0.zeroCount + 1
return { ...s0, zeroCount }
} else {
const decimalPart = s0.decimalPart + '0'.repeat(s0.zeroCount) + inp
return { ...s0, zeroCount: 0, decimalPart }
}
}
}
function reducer(str) {
let s = {
readingIntegerPart: true,
integerPart: '',
decimalPart: '',
zeroCount: 0,
}
for (const c of str.split('')) {
s = byCallbacks(s, c)
}
return byCallbacks(s, null)
}
// ----------
function* byGenerator() {
let inp
let s = {integerPart: '', decimalPart: ''}
while (inp = yield s) {
if (inp === '.') break
if (!(inp === '0' && s.integerPart === '')) {
const integerPart = s.integerPart + inp
s = { ...s, integerPart }
}
}
let zeroCount = 0
while (inp !== null && (inp = yield s)) {
if (inp === '0') {
zeroCount += 1
} else {
const decimalPart = s.decimalPart + '0'.repeat(zeroCount) + inp
zeroCount = 0
s = { ...s, decimalPart }
}
}
if (s.integerPart === '') {
const integerPart = s.integerPart = '0'
s = { ...s, integerPart }
}
return s.integerPart + (s.decimalPart ? `.${s.decimalPart}` : '')
}
function reducerWithGenerator(str) {
const gen = byGenerator()
gen.next()
for (const c of str.split('')) {
gen.next(c)
}
const result = gen.next(null)
if (!result.done) throw new Error('generator not ended')
return result.value
}
const testString = '00420.123040050000000000'
const r1 = reducer(testString)
const r2 = reducerWithGenerator(testString)
console.log('result', r1, r2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment