יחידה:גימטריה

מתוך אוצר הספרים היהודי השיתופי
גרסה מ־18:50, 19 במאי 2026 מאת עמד (שיחה | תרומות) (ניסוי מקווה שלא יפיל כלום)
קפיצה לניווט קפיצה לחיפוש

ניתן ליצור תיעוד על היחידה הזאת בדף יחידה:גימטריה/תיעוד

local char_to_val = {
    ['א'] = 1, ['ב'] = 2, ['ג'] = 3, ['ד'] = 4, ['ה'] = 5, ['ו'] = 6, ['ז'] = 7, ['ח'] = 8, ['ט'] = 9,
    ['י'] = 10, ['כ'] = 20, ['ל'] = 30, ['מ'] = 40, ['נ'] = 50, ['ס'] = 60, ['ע'] = 70, ['פ'] = 80, ['צ'] = 90,
    ['ק'] = 100, ['ר'] = 200, ['ש'] = 300, ['ת'] = 400, ['ך'] = 20, ['ם'] = 40, ['ן'] = 50, ['ף'] = 80, ['ץ'] = 90
}
local char_to_simple = {
    ['א'] = 1, ['ב'] = 2, ['ג'] = 3, ['ד'] = 4, ['ה'] = 5, ['ו'] = 6, ['ז'] = 7, ['ח'] = 8, ['ט'] = 9,
    ['י'] = 10, ['כ'] = 11, ['ך'] = 11, ['ל'] = 12, ['מ'] = 13, ['ם'] = 13, ['נ'] = 14, ['ן'] = 14,
    ['ס'] = 15, ['ע'] = 16, ['פ'] = 17, ['ף'] = 17, ['צ'] = 18, ['ץ'] = 18, ['ק'] = 19, ['ר'] = 20, ['ש'] = 21, ['ת'] = 22
}
local val_to_char = {
    [1] = 'א', [2] = 'ב', [3] = 'ג', [4] = 'ד', [5] = 'ה', [6] = 'ו', [7] = 'ז', [8] = 'ח', [9] = 'ט',
    [10] = 'י', [20] = 'כ', [30] = 'ל', [40] = 'מ', [50] = 'נ', [60] = 'ס', [70] = 'ע', [80] = 'פ', [90] = 'צ',
    [100] = 'ק', [200] = 'ר', [300] = 'ש', [400] = 'ת'
}
local to_sofit = { ['כ'] = 'ך', ['מ'] = 'ם', ['נ'] = 'ן', ['פ'] = 'ף', ['צ'] = 'ץ' }
local simple_chars = {"א","ב","ג","ד","ה","ו","ז","ח","ט","י","כ","ל","מ","נ","ס","ע","פ","צ","ק","ר","ש","ת"}

local gimatria, mispar_lotiot

gimatria = function(s, type_name, is_strict)
    if not s or s == "" then return 0 end
    type_name = type_name or 'רגיל'
    
    local function _calc(str, t_name)
        if t_name == 'פשוט' then
            if mw.ustring.len(str) ~= 1 or not char_to_simple[str] then return 0 end
            return char_to_simple[str]
        end
        if t_name == 'אלפים' then
            local pos = mw.ustring.find(str, "'")
            if pos then
                local prefix = mw.ustring.sub(str, 1, pos - 1)
                local suffix = mw.ustring.sub(str, pos + 1)
                return _calc(prefix, 'רגיל') * 1000 + _calc(suffix, 'רגיל')
            end
        end
        local sum = 0
        for l in mw.ustring.gmatch(str, ".") do sum = sum + (char_to_val[l] or 0) end
        return sum
    end
    
    local val = _calc(s, type_name)
    
    if is_strict and val > 0 then
        local clean_s = mw.ustring.gsub(s, "['\"]", "")
        local rev_str = mispar_lotiot(val, "", type_name, "לא")
        if rev_str ~= clean_s then error("Strict gimatria mismatch") end
    end
    
    if val == 0 then error("Invalid gimatria") end
    return val
end

mispar_lotiot = function(num, geresh, type_name, use_sofit)
    local n = math.floor(tonumber(num) or 0)
    type_name = type_name or 'רגיל'
    if type_name == 'פשוט' and (n < 1 or n > 22) then
        error("קלט לא תקין למצב פשוט: נדרש מספר בטווח 1-22")
    end
    if n <= 0 then return "" end
    if type_name == 'אלפים' then
        local thousands = math.floor(n / 1000)
        local remainder = n % 1000
        if thousands > 0 then
            return mispar_lotiot(thousands, "", 'רגיל') .. "'" .. mispar_lotiot(remainder, geresh, 'רגיל', use_sofit)
        end
    end
    local final_str = ""
    if type_name == 'פשוט' then
        final_str = simple_chars[n]
    else
        local res_table = {}
        local temp_n = n
        local tav_count = math.floor(temp_n / 400)
        if tav_count > 0 then table.insert(res_table, string.rep('ת', tav_count)) temp_n = temp_n % 400 end
        while temp_n > 0 do
            local toadd = (temp_n >= 100) and (temp_n - temp_n % 100) or (temp_n >= 10 and (temp_n - temp_n % 10) or temp_n)
            table.insert(res_table, val_to_char[toadd] or "")
            temp_n = temp_n - toadd
        end
        final_str = table.concat(res_table)
    end
    final_str = mw.ustring.gsub(final_str, 'יה', 'טו'):gsub('יו', 'טז')
    
    if use_sofit == "כן" then
        local last_char = mw.ustring.sub(final_str, -1)
        if to_sofit[last_char] then
            final_str = mw.ustring.sub(final_str, 1, -2) .. to_sofit[last_char]
        end
    end
    
    local actual_geresh = geresh
    if geresh == "'\"" or geresh == "\"'" or geresh == '"\'' then
        actual_geresh = (mw.ustring.len(final_str) > 1) and '"' or "'"
    end
    if actual_geresh and actual_geresh ~= "" then
        if mw.ustring.len(final_str) > 1 then
            final_str = mw.ustring.gsub(final_str, "(.)(.)$", "%1" .. actual_geresh .. "%2")
        else
            final_str = final_str .. actual_geresh
        end
    end
    return final_str
end

local function get_arg(frame, name_or_idx)
    local args = frame.args
    if args[name_or_idx] == nil or args[name_or_idx] == "" then
        args = frame:getParent().args
    end
    return args[name_or_idx] or ""
end

return {
    ['גימטריה'] = function(frame) return gimatria(get_arg(frame, 1), get_arg(frame, 2), false) end,
    ['מספר לאות'] = function(frame) return mispar_lotiot(get_arg(frame, 1), get_arg(frame, 2), get_arg(frame, 3), get_arg(frame, "אות סופית")) end,
    ['הבא'] = function(frame) return mispar_lotiot(gimatria(get_arg(frame, 1), get_arg(frame, 2), false) + 1, get_arg(frame, 4), get_arg(frame, 3), get_arg(frame, "אות סופית")) end,
    ['הקודם'] = function(frame) 
        local val = gimatria(get_arg(frame, 1), get_arg(frame, 2), false) - 1
        return (val > 0) and mispar_lotiot(val, get_arg(frame, 4), get_arg(frame, 3), get_arg(frame, "אות סופית")) or ""
    end,
    gimatria = gimatria,
    mispar_lotiot = mispar_lotiot
}