AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79592023
Accepted
Lance Pollard
Lance Pollard
Asked: 2025-04-25 15:32:42 +0800 CST2025-04-25 15:32:42 +0800 CST 2025-04-25 15:32:42 +0800 CST

Como criar um layout que tenha apenas todos os tamanhos de linhas pares ou ímpares e mude em apenas 2?

  • 772

Tenho iterado com o Claude 3.7 Sonnet e o ChatGPT 4o por dias e dias, tentando fazer com que fique exatamente como eu quero, mas ele continua cometendo erros no algoritmo e, de vez em quando, cometendo os mesmos erros, basicamente em um círculo vicioso.

Como faço para criar um "layout" (matriz de inteiros), que representa uma grade, que tem as seguintes restrições:

  1. A função é generateGridLayout(n, minColumns, maxColumns), onde na prática ela é normalmente chamada de gen(n, 3, 7), mas em teoria poderia ser qualquer coisa que formaria uma grade legal, gen(n, 2, 256)como o intervalo máximo.
  2. Ele deve manipular um número arbitrário de elementos (digamos, até Number.MAX_SAFE_INTEGER, que é 9007199254740991, mas, na prática, meus "layouts de grade" terão apenas até 1000 itens).
  3. Se o número de itens nfor ímpar, cada linha deverá ter apenas um número ímpar de valores. Se nfor par, cada linha poderá ter números pares ou ímpares (pense em 30, podem ser 10 linhas de 3, ou 3 linhas de 10).
  4. As linhas só podem diferir 2em tamanho, sempre decrescente. Elas nunca podem diferir em 3, 4, etc. Isso significa que 7 NÃO PODE ser [5, 2] ou [4, 4, 1], pois esses têm saltos > 2. Só pode ser [7] ou [3, 3, 1], se gen(7, 3, 7).
  5. (nota meta: isso é para um layout de interface de usuário, então é baseado no tamanho da janela de visualização/contêiner, então se dissermos "máximo 7", mas houver espaço apenas para 5, ele definirá o máximo como 5, mas esse fato não é realmente relevante para a solução)
  6. Se dissermos "máximo é 7", mas houver um número par de itens, e o número par não puder satisfazer "todas as linhas pares ou ímpares", então tente maxColumns - 1, e assim por diante, até minColumns.
  7. Importante: deve minimizar o número de linhas pequenas. Portanto, para 29, com 6 maxColumns, deve ser [5, 5, 5, 5, 5, 3, 1], e não [5, 5, 5, 5, 3, 3, 3]. Ou seja, maximiza o número de linhas grandes e minimiza o número de linhas pequenas. Da mesma forma, para 29, definitivamente não deve ser [5, 5, 5, 5, 3, 3, 1, 1, 1].

Aqui estão alguns exemplos para demonstrar o objetivo:

31
[5, 5, 5, 5, 5, 3, 3]
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1]

30
[5, 5, 5, 5, 5, 5]
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]

29
[5, 5, 5, 5, 5, 3, 1]
[3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1]

28
[6, 6, 6, 6, 4]
[4, 4, 4, 4, 4, 4, 4]

27
[5, 5, 5, 5, 3, 3, 1]
[3, 3, 3, 3, 3, 3, 3, 3, 3]

26
[6, 6, 6, 4, 2, 2]
[4, 4, 4, 4, 4, 4, 4]

23
[5, 5, 5, 5, 3]
[3, 3, 3, 3, 3, 3, 3, 1, 1]

Elas mostram, se 5 ou 6 forem o máximo de colunas, o que ele faria, e o que deveria fazer se 4 ou 3 forem o máximo de colunas.

Por exemplo, 26 em 7 colunas no máximo NÃO devem ser:

[6, 6, 6, 6, 2] # jumps more than 2
[4, 4, 4, 4, 4, 4, 2] # doesn't maximize maxColumns

O ideal seria:

[6, 6, 6, 4, 2, 2] # jumps max 2, maximizes large columns, minimizes small columns.

Aqui está minha solução atual:

log(29, 2, 7)
log(29, 2, 6)
log(29, 2, 5)
log(29, 2, 4)
log(44, 2, 3)

function distributeGridLayout(
  length,
  minColumns,
  maxColumns
) {
  function recur(
    dp,
    length,
    width,
  ) {
    if (length == 0) {
      return []
    }

    if (length < width - 2 || width <= 0) {
      return
    }

    if (dp[width].has(length)) {
      return
    }

    dp[width].add(length)

    for (let i = 0; i < 2; i++) {
      let result = recur(dp, length - width, width)
      if (result) {
        return [width, ...result]
      }
      width -= 2
    }

    return
  }

  if (length <= maxColumns) {
    return [length]
  }

  if (maxColumns >= 3 && length === 7) {
    return [3, 3, 1]
  }

  if (maxColumns >= minColumns && length % maxColumns === 0) {
    const result = []
    while (length) {
      result.push(maxColumns)
      length -= maxColumns
    }
    return result
  }

  if (maxColumns > 4) {
    if (maxColumns > minColumns && length % (maxColumns - 1) === 0) {
      const result = []
      maxColumns--
      while (length) {
        result.push(maxColumns)
        length -= maxColumns
      }
      return result
    }
  }

  const dec = 2 - (length % 2)

  maxColumns -= maxColumns % dec

  const dp = Array.from(
    { length: maxColumns + 1 },
    () => new Set(),
  )

  for (let width = maxColumns; width > 0; width -= dec) {
    const result = recur(dp, length - width, width)
    if (result) {
      if (width <= minColumns) {
        return
      }
      return [width, ...result]
    }
  }

  return
}

function log(n, min, max) {
  const grid = distributeGridLayout(n, min, max)
  console.log(`gen(${n}, ${min}, ${max})`, grid)
}

Isso funciona para a maioria, como este layout tibetano (29 caracteres):

Mas não está funcionando para este layout tailandês (44 caracteres, em 2-3 colunas), aqui está o final (na minha interface, se o algoritmo retornar indefinido, ele volta para um layout de grade básico):

O que preciso mudar exatamente para que isso sempre se ajuste às minhas regras? O layout 44 de 3 no máximo e 2 minutos deve ser basicamente um layout de 2 colunas...

javascript
  • 1 1 respostas
  • 85 Views

1 respostas

  • Voted
  1. Best Answer
    trincot
    2025-04-26T00:34:24+08:002025-04-26T00:34:24+08:00

    Isso parece uma evolução de uma de suas perguntas anteriores , com pelo menos a diferença de que aqui temos um minColumnsrequisito.

    Não entendi muito bem por que no seu código há um tratamento específico para o caso length==7.

    Além disso, os dois blocos que verificam length % maxColumns === 0e length % (maxColumns - 1) === 0parecem bastante arbitrários (como, por que então não também length % (maxColumns - 2) === 0, ...etc?): eles não parecem casos limites reais que precisam de tratamento especial.

    A condição de saída dentro do loop principal, quando width <= minColumns, não deve depender de você ter obtido um resultado bem-sucedido, mas pode ter sido considerada como uma forcondição de loop (o oposto disso).

    Há também um problema com maxColumns -= maxColumns % dec: ele torna maxColumnspar quando era ímpar e lengthé par. Em vez disso, você vai querer maxColumnsque seja tornado ímpar quando lengthé ímpar. Não me lembro por que isso aconteceu na resposta à sua pergunta anterior, onde a pergunta tinha menos especificações. De qualquer forma, isso precisa ser alterado. Pode ser mais fácil para a manutenção do código ter apenas uma condição dentro do loop principal.

    Parece haver pelo menos dois erros nos resultados esperados:

    26
    [6, 6, 6, 4, 2, 2]
    [4, 4, 4, 4, 4, 4, 4]
    

    Vou assumir que deveria ser:

    26
    [6, 6, 6, 4, 4]         // because of rule 7
    [4, 4, 4, 4, 4, 4, 2]   // because sum must be 26
    

    Aqui está o código corrigido com alguns dos seus casos de teste.

    function distribute(length, minColumns, maxColumns) {
        const dp = Array.from({length: maxColumns + 1}, () => new Set());
    
        function recur(length, width) {
            if (length === 0) return [];
            if (length < width - 2 || width <= 0) return null;
            if (dp[width].has(length)) return null;
            dp[width].add(length);
            for (let i = 0; i < 2; i++) {
                let result = recur(length - width, width);
                if (result) return [width, ...result];
                width -= 2;
            }
            return null;
        }
        
        for (let width = maxColumns; width >= minColumns; width--) {
            // An odd length cannot be fulfilled with an even column count
            if (length % 2 > width % 2) continue; 
            const result = recur(length - width, width);
            if (result) return [width, ...result];
        }
        return null;
    }
    
    const tests = [
        // [length, minColumns, maxColumns, ...expected result]
        [31, 1, 6, 5, 5, 5, 5, 5, 3, 3],
        [31, 1, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1],
        [30, 1, 5, 5, 5, 5, 5, 5, 5],
        [30, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
        [29, 1, 6, 5, 5, 5, 5, 5, 3, 1],
        [29, 1, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1],
        [28, 1, 6, 6, 6, 6, 6, 4],
        [28, 1, 4, 4, 4, 4, 4, 4, 4, 4],
        [27, 1, 6, 5, 5, 5, 5, 3, 3, 1],
        [27, 1, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3],
        [26, 1, 6, 6, 6, 6, 4, 4],
        [26, 1, 4, 4, 4, 4, 4, 4, 4, 2],
        [23, 1, 6, 5, 5, 5, 5, 3],
        [23, 1, 4, 3, 3, 3, 3, 3, 3, 3, 1, 1],
        [29, 2, 7, 7, 7, 7, 5, 3],
        [29, 2, 6, 5, 5, 5, 5, 5, 3, 1],
        [44, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1],
        [7, 2, 6, 3, 3, 1],
    ];
    
    for (const [length, minColumns, maxColumns, ...expected] of tests) {
        const result = distribute(length, minColumns, maxColumns);
        if (JSON.stringify(result) !== JSON.stringify(expected)) {
            throw Error(`Expected distribute(${length}, ${minColumns}, ${maxColumns}) to return ${JSON.stringify(expected)}, but got ${JSON.stringify(result)}`);
        }
    }
    console.log("All tests passed successfully.");

    • 2

relate perguntas

  • classificação de mesclagem não está funcionando - código Javascript: não é possível encontrar o erro mesmo após a depuração

  • método select.remove() funciona estranho [fechado]

  • Sempre um 401 res em useOpenWeather () - react-open-weather lib [duplicado]

  • O elemento de entrada não possui atributo somente leitura, mas os campos ainda não podem ser editados [fechado]

  • Como editar o raio do primeiro nó de um RadialTree D3.js?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve