Проверьте, является ли число делимым 3 [закрытый]

Вы можете полностью отказаться от вызова функции и просто использовать DateDiff для вычисления количества минут между каждой записью, используя цикл For-Next для итеративного добавления минуты в итерации к startTime

Option Explicit
Sub TimeSheet()
    Dim timeEntries As Range
    Dim entry As Range
    Dim startTime As Date
    Dim endTime As Date
    Dim lastRow As Long
    Dim minutes As Long
    Dim m As Long

    Set timeEntries = Worksheets("Input").Range("A2:A3")

    For Each entry In timeEntries
        startTime = entry.Offset(0, 1)
        endTime = entry.Offset(0, 2)

        minutes = DateDiff("n", startTime, endTime)
        With Worksheets("Output")
            For m = 1 To minutes - 1
                lastRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
                .Range("A" & lastRow) = entry
                .Range("B" & lastRow) = Format(startTime + (m / 1440), "dd.mm.yyyy hh:mm:00")
            Next m
        End With
    Next entry
End Sub

Это привело к результатам:

A   23.03.2018 08:17:00
A   23.03.2018 08:18:00
A   23.03.2018 08:19:00
A   23.03.2018 08:20:00
....
A   23.03.2018 13:55:00
B   23.03.2018 11:17:00
B   23.03.2018 11:18:00
B   23.03.2018 11:19:00
B   23.03.2018 11:20:00
....
B   23.03.2018 13:55:00
18
задан Andrew Eisenberg 4 May 2012 в 03:46
поделиться

10 ответов

Heh

State table for LSB:

S I S' O
0 0 0  1
0 1 1  0
1 0 2  0
1 1 0  1
2 0 1  0
2 1 2  0

Explanation: 0 is divisible by three. 0 << 1 + 0 = 0. Repeat using S = (S << 1 + I) % 3 and O = 1 if S == 0.

State table for MSB:

S I S' O
0 0 0  1
0 1 2  0
1 0 1  0
1 1 0  1
2 0 2  0
2 1 1  0

Explanation: 0 is divisible by three. 0 >> 1 + 0 = 0. Repeat using S = (S >> 1 + I) % 3 and O = 1 if S == 0.

S' is different from above, but O works the same, since S' is 0 for the same cases (00 and 11). Since O is the same in both cases, O_LSB = O_MSB, so to make MSB as short as LSB, or vice-versa, just use the shortest of both.

12
ответ дан 30 November 2019 в 05:44
поделиться

Существует довольно известный прием, позволяющий определить, кратно ли число 11, путем попеременного добавления и вычитания его десятичных цифр. Если число, которое вы получаете в конце, кратно 11, то число, с которого вы начали, также кратно 11:

47278    4 - 7 + 2 - 7 + 8 = 0, multiple of 11     (47278 = 11 * 4298)
52214    5 - 2 + 2 - 1 + 4 = 8, not multiple of 11 (52214 = 11 * 4746 + 8)

Мы можем применить тот же трюк к двоичным числам. Двоичное число кратно 3 тогда и только тогда, когда чередующаяся сумма его битов также кратна 3:

4   = 100       1 - 0 + 0 = 1, not multiple of 3
6   = 110       1 - 1 + 0 = 0, multiple of 3
78  = 1001110   1 - 0 + 0 - 1 + 1 - 1 + 0 = 0, multiple of 3
109 = 1101101   1 - 1 + 0 - 1 + 1 - 0 + 1 = 1, not multiple of 3

Не имеет значения, начинаете ли вы с MSB или LSB, поэтому следующая функция Python работает одинаково хорошо в обоих случаях. Требуется итератор, который возвращает биты по одному. multiplier чередуется между 1 и 2 вместо 1 и -1, чтобы избежать взятия по модулю отрицательного числа.

def divisibleBy3(iterator):

    multiplier = 1
    accumulator = 0

    for bit in iterator:
        accumulator = (accumulator + bit * multiplier) % 3
        multiplier = 3 - multiplier

    return accumulator == 0
27
ответ дан 30 November 2019 в 05:44
поделиться

The idea is that the number can grow arbitrarily long, which means you can't use mod 3 here, since your number will grow beyond the capacity of your integer class.

The idea is to notice what happens to the number. If you're adding bits to the right, what you're actually doing is shifting left one bit and adding the new bit.

Shift-left is the same as multiplying by 2, and adding the new bit is either adding 0 or 1. Assuming we started from 0, we can do this recursively based on the modulo-3 of the last number.

last | input || next | example
------------------------------------
0    | 0     || 0    | 0 * 2 + 0 = 0
0    | 1     || 1    | 0 * 2 + 1 = 1
1    | 0     || 2    | 1 * 2 + 0 = 2
1    | 1     || 0    | 1 * 2 + 1 = 0 (= 3 mod 3)
2    | 0     || 1    | 2 * 2 + 0 = 1 (= 4 mod 3)
2    | 1     || 2    | 2 * 2 + 1 = 2 (= 5 mod 3)

Now let's see what happens when you add a bit to the left. First, notice that:

22n mod 3 = 1

and

22n+1 mod 3 = 2

So now we have to either add 1 or 2 to the mod based on if the current iteration is odd or even.

last | n is even? | input || next | example
-------------------------------------------
d/c  | don't care | 0     || last | last + 0*2^n = last
0    | yes        | 1     || 0    | 0 + 1*2^n = 1 (= 2^n mod 3)
0    | no         | 1     || 0    | 0 + 1*2^n = 2 (= 2^n mod 3)
1    | yes        | 1     || 0    | 1 + 1*2^n = 2
1    | no         | 1     || 0    | 1 + 1*2^n = 0 (= 3 mod 3)
1    | yes        | 1     || 0    | 2 + 1*2^n = 0
1    | no         | 1     || 0    | 2 + 1*2^n = 1
4
ответ дан 30 November 2019 в 05:44
поделиться

You need to do all calculations using arithmetic modulo 3. This is the way

MSB:

number=0
while(!eof)
    n=input()
    number=(number *2 + n) mod 3

if(number == 0)
    print divisible

LSB:

number = 0;
multiplier = 1;
while(!eof)
    n=input()
    number = (number + multiplier * n) mod 3
    multiplier = (multiplier * 2) mod 3

if(number == 0)
   print divisible

This is general idea...

Now, your part is to understand why this is correct.

And yes, do homework yourself ;)

7
ответ дан 30 November 2019 в 05:44
поделиться

Here is an simple way to do it by hand. Since 1 = 22 mod 3, we get 1 = 22n mod 3 for every positive integer. Furthermore 2 = 22n+1 mod 3. Hence one can determine if an integer is divisible by 3 by counting the 1 bits at odd bit positions, multiply this number by 2, add the number of 1-bits at even bit posistions add them to the result and check if the result is divisible by 3.

Example: 5710=1110012. There are 2 bits at odd positions, and 2 bits at even positions. 2*2 + 2 = 6 is divisible by 3. Hence 57 is divisible by 3.

Here is also a thought towards solving question c). If one inverts the bit order of a binary integer then all the bits remain at even/odd positions or all bits change. Hence inverting the order of the bits of an integer n results is an integer that is divisible by 3 if and only if n is divisible by 3. Hence any solution for question a) works without changes for question b) and vice versa. Hmm, maybe this could help to figure out which approach is faster...

9
ответ дан 30 November 2019 в 05:44
поделиться

Actually the LSB method would actually make this easier. In C:

MSB method:

/* 
Returns 1 if divisble by 3, otherwise 0
Note: It is assumed 'input' format is valid
*/
int is_divisible_by_3_msb(char *input) {
  unsigned value = 0;
  char *p = input;
  if (*p == '1') {
    value &= 1;
  }
  p++;
  while (*p) {
    if (*p != ',') {
      value <<= 1;
      if (*p == '1') {
        ret &= 1;
      }
    }
    p++;
  }
  return (value % 3 == 0) ? 1 : 0;
}

LSB method:

/* 
Returns 1 if divisble by 3, otherwise 0
Note: It is assumed 'input' format is valid
*/
int is_divisible_by_3_lsb(char *input) {
  unsigned value = 0;
  unsigned mask = 1;
  char *p = input;
  while (*p) {
    if (*p != ',') {
      if (*p == '1') {
        value &= mask;
      }
      mask <<= 1;
    }
    p++;
  }
  return (value % 3 == 0) ? 1 : 0;
}

Personally I have a hard time believing one of these will be significantly different to the other.

0
ответ дан 30 November 2019 в 05:44
поделиться

I think Nathan Fellman is on the right track for part a and b (except b needs an extra piece of state: you need to keep track of if your digit position is odd or even).

I think the trick for part C is negating the last value at each step. I.e. 0 goes to 0, 1 goes to 2 and 2 goes to 1.

-1
ответ дан 30 November 2019 в 05:44
поделиться

Число делится на 3, если сумма его цифр делится на 3.

Таким образом, вы можете сложить цифры и получить сумму:

  • , если сумма больше или равно 10, используйте тот же метод
  • , если он 3, 6, 9, тогда он делится
  • , если сумма отличается от 3, 6, 9, тогда не делится
-1
ответ дан 30 November 2019 в 05:44
поделиться
input  "0":       (0)  output 1
inputs "1,0,0":   (4)  output 0
inputs "1,1,0,0": (6)  output 1

Разве последний ввод не должен быть 12 , или я неправильно понимаю вопрос?

0
ответ дан 30 November 2019 в 05:44
поделиться

Вот ... кое-что новенькое ... как проверить, делится ли двоичное число любой длины (даже тысячи цифр) на 3.

divisible-by-3 state machine

-->((0))<---1--->()<---0--->(1)        ASCII representation of graph

Из рисунка.

  1. Вы начинаете с двойного круга.
  2. Когда вы получаете единицу или ноль, если цифра находится внутри круга, вы остаетесь в этом круге. Однако, если цифра находится на линии, вы перемещаетесь через линию.
  3. Повторяйте шаг два, пока не будут поглощены все цифры.
  4. Если вы в конечном итоге окажетесь в двойном круге, то двоичное число делится на 3.

Вы также можете использовать это для генерации чисел, делящихся на 3. И я бы не подумал, что будет трудно преобразовать это в цепь.

1 пример с использованием графика ...

11000000000001011111111111101 делится на 3 (снова заканчивается двойным кружком)

Попробуйте сами.

Вы также можете проделать аналогичные уловки для выполнения MOD 10, для преобразования двоичных чисел в числа с основанием 10. (10 кружков, каждый из которых обведен вдвое, и представляют значения от 0 до 9, полученные по модулю)

РЕДАКТИРОВАТЬ: Это для цифр, идущих слева направо, нетрудно изменить конечный автомат, чтобы он принял обратный язык хотя.

ПРИМЕЧАНИЕ: В представлении ASCII графика () обозначает одиночный круг, а (()) обозначает двойной круг.В конечных автоматах это называется состояниями, а двойной кружок - это состояние принятия (состояние, которое означает, что в конечном итоге оно делится на 3)

20
ответ дан 30 November 2019 в 05:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: